├── .gitignore ├── ch06 ├── myModule │ ├── README.md │ ├── go.mod │ ├── myModule.go │ └── .gitignore ├── htmlT.db ├── useV2 │ ├── useV2.go │ └── useUpdatedV2.go ├── text.gotext ├── useV1 │ ├── useModule.go │ └── useUpdatedModule.go ├── a.go ├── b.go ├── manyInit.go ├── useTwoVersions │ └── useTwo.go ├── useAPackage.go ├── ptrFun.go ├── returnPtr.go ├── aPackage.go ├── returnFunction.go ├── funFun.go ├── useSyscall.go ├── variadic.go ├── html.gohtml ├── textT.go ├── functions.go ├── goParser.go ├── goScanner.go ├── returnNames.go ├── varTimes.go └── htmlT.go ├── ch14 ├── reg_data.txt ├── data.txt ├── neural.go ├── tfVersion.go ├── readKafka.go ├── anomaly.go ├── classify.go ├── cluster.go ├── regression.go └── writeKafka.go ├── ch10 ├── closeNilChannel.go ├── maxprocs.go ├── cloGo.go ├── cloGoCorrect.go ├── endlessComp.go ├── forgetMutex.go ├── bufChannel.go ├── nilChannel.go ├── moreContext.go ├── defineOrder.go ├── timeOut1.go ├── sillySort.go ├── raceC.go ├── noRaceC.go ├── atom.go ├── slowWWW.go ├── select.go ├── mutex.go ├── chSquare.go ├── timeOut2.go ├── monitor.go ├── rwMutex.go └── workerPool.go ├── ch08 ├── dataFile ├── viper │ ├── myConfig.yaml │ ├── myJSONConfig.json │ ├── useViper.go │ ├── flagToViper.go │ ├── readJSON.go │ └── readYAML.go ├── ebpf.go ├── simpleFlag.go ├── ids.go ├── devRandom.go ├── permissions.go ├── cobra │ ├── aliases │ │ ├── cmd │ │ │ ├── preferences.go │ │ │ └── initialization.go │ │ └── main.go │ └── cli │ │ ├── main.go │ │ └── cmd │ │ └── cmdOne.go ├── handleTwo.go ├── bytes.go ├── str.go ├── handleAll.go ├── cat.go ├── ptraceRegs.go ├── byLine.go ├── byCharacter.go ├── readSize.go ├── byWord.go ├── funWithFlag.go ├── save.go ├── dockerAPI.go └── CSVplot.go ├── ch07 ├── myInterface.go ├── ooo.go ├── debug │ └── main.go ├── assertion.go ├── methods.go ├── goCoIn.go ├── switch.go ├── useInterface.go ├── reflection.go ├── walkRef.go └── advRefl.go ├── ch02 ├── callClib │ ├── callC.h │ └── callC.c ├── nodeTree.go ├── wasm │ ├── toWasm.go │ └── index.html ├── justPanic.go ├── mapNoStar.go ├── mapStar.go ├── nodeTreeMore.go ├── cGo.go ├── usedByC.go ├── willUseGo.c ├── sliceGC.go ├── mapSplit.go ├── goEnv.go ├── unsafe.go ├── requiredVersion.go ├── defer.go ├── callC.go ├── panicRecover.go ├── moreUnsafe.go ├── gColl.go └── logDefer.go ├── ch11 ├── asm │ ├── add_amd64.s │ └── add_me.go ├── machineCode.go ├── ex.go ├── quick.go ├── xCompile.go ├── too_long.go ├── ex_test.go ├── documentMe_test.go ├── cover │ ├── codeCover.go │ └── codeCover_test.go ├── randomBuiltin.go ├── cannotReach.go ├── testMe.go ├── too_long_test.go ├── quick_test.go ├── documentMe.go ├── benchmarkMe.go ├── writingBU_test.go ├── graph.dot ├── betterProfile.go ├── testMe_test.go ├── goGC.go ├── Docker │ └── Dockerfile ├── writingBU.go └── benchmarkMe_test.go ├── ch01 ├── hw.go ├── packageNotUsed.go ├── aSourceFile.go ├── curly.go ├── packageNotUsedUnderscore.go ├── Dockerfile ├── getPackage.go ├── stdIN.go ├── stdOUT.go ├── logFatal.go ├── logPanic.go ├── printing.go ├── stdERR.go ├── customLog.go ├── cla.go ├── customLogLineNumber.go ├── logFiles.go ├── newError.go └── errors.go ├── ch13 ├── Docker │ └── Dockerfile ├── sharedRPC.go ├── HTTPS │ ├── server.key │ ├── https.go │ ├── server.crt │ ├── httpsClient.go │ ├── TLSserver.go │ ├── client.crt │ └── TLSclient.go ├── lowLevel.go ├── TCPclient.go ├── syscallNet.go ├── RPCclient.go ├── TCPserver.go ├── otherTCPclient.go ├── otherTCPserver.go ├── UDPclient.go ├── RPCserver.go ├── UDPserver.go └── fiboTCP.go ├── ch05 ├── OK.txt ├── noOK1.txt ├── dimensions.go ├── conRing.go ├── generatePassword.go ├── conList.go ├── cryptoRand.go ├── conHeap.go ├── hashTable.go ├── binTree.go ├── randomNumbers.go ├── stack.go ├── hashTableLookup.go └── queue.go ├── ch03 ├── failMap.go ├── reslice.go ├── appendArrayToSlice.go ├── mapNoStarTime.go ├── mapStarTime.go ├── parseTime.go ├── sliceGCTime.go ├── parseDate.go ├── mapSplitTime.go ├── usingTime.go ├── pointers.go ├── deleteSlice.go ├── usingMaps.go ├── lenCap.go ├── loops.go ├── numbers.go ├── execTime.go ├── constants.go ├── slices.go ├── sortSlice.go ├── usingArrays.go ├── copySlice.go └── timeDate.go ├── ch04 ├── readMe.json ├── noStr.json ├── unicode.go ├── tuples.go ├── data.xml ├── logEntries.txt ├── structures.go ├── runes.go ├── parsingJSON.go ├── pointerStruct.go ├── writeJSON.go ├── mUJSON.go ├── readJSON.go ├── readXML.go ├── modXML.go ├── strings.go ├── selectColumn.go ├── findIPv4.go ├── switch.go ├── rwXML.go └── changeDT.go ├── ch09 ├── writeCh.go ├── simple.go ├── readClose.go ├── create.go ├── readCh.go ├── syncGo.go ├── pipeline.go └── plNoRace.go ├── ch12 ├── gRPC │ ├── api.proto │ ├── gServer.go │ └── gClient.go ├── MXrecords.go ├── NSrecords.go ├── netCapabilities.go ├── home.gohtml ├── webClient.go ├── netConfig.go ├── atomWWW.go ├── anotherTimeOut.go ├── insert.gohtml ├── update.gohtml ├── testWWW.go ├── www.go ├── DNS.go ├── testWWW_test.go ├── serverTimeOut.go ├── clientTimeOut.go ├── httpTrace.go ├── wwwProfile.go └── advancedWebClient.go ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /ch06/myModule/README.md: -------------------------------------------------------------------------------- 1 | # myModule 2 | Sample Go module 3 | -------------------------------------------------------------------------------- /ch06/myModule/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mactsouk/myModule 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /ch14/reg_data.txt: -------------------------------------------------------------------------------- 1 | 1,2 2 | 3,4.0 3 | 2.1,3 4 | 4,4.2 5 | 5,5.1 6 | -5,-5.1 7 | -------------------------------------------------------------------------------- /ch06/htmlT.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Mastering-Go-Second-Edition/HEAD/ch06/htmlT.db -------------------------------------------------------------------------------- /ch10/closeNilChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var c chan string 5 | close(c) 6 | } 7 | -------------------------------------------------------------------------------- /ch14/data.txt: -------------------------------------------------------------------------------- 1 | 1.2 2 | -2 3 | 1 4 | 2.0 5 | not valid 6 | 3 7 | 10 8 | 100 9 | -10 10 | -100 11 | -------------------------------------------------------------------------------- /ch08/dataFile: -------------------------------------------------------------------------------- 1 | 1,2 2 | 2,3 3 | 3,3 4 | 4,4 5 | 5,8 6 | 6,5 7 | -1,12 8 | -2,10 9 | -3,10 10 | -4,10 11 | -------------------------------------------------------------------------------- /ch08/viper/myConfig.yaml: -------------------------------------------------------------------------------- 1 | item1: 2 | k1: 3 | - true 4 | k2: 5 | - myValue 6 | -------------------------------------------------------------------------------- /ch07/myInterface.go: -------------------------------------------------------------------------------- 1 | package myInterface 2 | 3 | type Shape interface { 4 | Area() float64 5 | Perimeter() float64 6 | } 7 | -------------------------------------------------------------------------------- /ch02/callClib/callC.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLC_H 2 | #define CALLC_H 3 | 4 | void cHello(); 5 | void printMessage(char* message); 6 | 7 | #endif -------------------------------------------------------------------------------- /ch11/asm/add_amd64.s: -------------------------------------------------------------------------------- 1 | TEXT ·add(SB),$0 2 | MOVQ x+0(FP), BX 3 | MOVQ y+8(FP), BP 4 | ADDQ BP, BX 5 | MOVQ BX, ret+16(FP) 6 | RET 7 | -------------------------------------------------------------------------------- /ch01/hw.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello World!") 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch02/nodeTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello there!") 9 | } 10 | -------------------------------------------------------------------------------- /ch01/packageNotUsed.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello there!") 10 | } 11 | -------------------------------------------------------------------------------- /ch06/myModule/myModule.go: -------------------------------------------------------------------------------- 1 | package myModule 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func Version() { 8 | fmt.Println("Version 1.1.0") 9 | } 10 | -------------------------------------------------------------------------------- /ch01/aSourceFile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("This is a sample Go program!") 9 | } 10 | -------------------------------------------------------------------------------- /ch06/useV2/useV2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | v "github.com/mactsouk/myModule/v2" 5 | ) 6 | 7 | func main() { 8 | v.Version() 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch02/wasm/toWasm.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Creating WebAssembly code from Go!") 9 | } 10 | -------------------------------------------------------------------------------- /ch06/text.gotext: -------------------------------------------------------------------------------- 1 | Calculating the squares of some integers 2 | 3 | {{ range . }} The square of {{ printf "%d" .Number}} is {{ printf "%d" .Square}} 4 | {{ end }} 5 | -------------------------------------------------------------------------------- /ch06/useV1/useModule.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | v1 "github.com/mactsouk/myModule" 5 | ) 6 | 7 | func main() { 8 | v1.Version() 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch08/ebpf.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/iovisor/gobpf" 6 | "os" 7 | "unsafe" 8 | ) 9 | 10 | func main() { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ch01/curly.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() 8 | { 9 | fmt.Println("Go has strict rules for curly braces!") 10 | } 11 | 12 | -------------------------------------------------------------------------------- /ch01/packageNotUsedUnderscore.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | _ "os" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello there!") 10 | } 11 | -------------------------------------------------------------------------------- /ch06/useV1/useUpdatedModule.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | v1 "github.com/mactsouk/myModule" 5 | ) 6 | 7 | func main() { 8 | v1.Version() 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch06/useV2/useUpdatedV2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | v "github.com/mactsouk/myModule/v2" 5 | ) 6 | 7 | func main() { 8 | v.Version() 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch01/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | RUN mkdir /files 4 | COPY hw.go /files 5 | WORKDIR /files 6 | 7 | RUN go build -o /files/hw hw.go 8 | ENTRYPOINT ["/files/hw"] 9 | -------------------------------------------------------------------------------- /ch11/asm/add_me.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func add(x, y int64) int64 8 | 9 | func main() { 10 | fmt.Println(add(1, 2)) 11 | } 12 | -------------------------------------------------------------------------------- /ch06/a.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func init() { 8 | fmt.Println("init() a") 9 | } 10 | 11 | func FromA() { 12 | fmt.Println("fromA()") 13 | } 14 | -------------------------------------------------------------------------------- /ch11/machineCode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func hello() { 8 | fmt.Println("Hello!") 9 | } 10 | 11 | func main() { 12 | hello() 13 | } 14 | -------------------------------------------------------------------------------- /ch01/getPackage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mactsouk/go/simpleGitHub" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(simpleGitHub.AddTwo(5, 6)) 10 | } 11 | -------------------------------------------------------------------------------- /ch13/Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:latest 2 | 3 | RUN mkdir /files 4 | COPY kvTCP.go /files 5 | WORKDIR /files 6 | 7 | RUN go build -o /files/kvTCP kvTCP.go 8 | ENTRYPOINT ["/files/kvTCP","80"] 9 | -------------------------------------------------------------------------------- /ch06/b.go: -------------------------------------------------------------------------------- 1 | package b 2 | 3 | import ( 4 | "a" 5 | "fmt" 6 | ) 7 | 8 | func init() { 9 | fmt.Println("init() b") 10 | } 11 | 12 | func FromB() { 13 | fmt.Println("fromB()") 14 | a.FromA() 15 | } 16 | -------------------------------------------------------------------------------- /ch05/OK.txt: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | 5 7 8 1 3 9 6 2 4 3 | 4 9 6 8 7 2 1 5 3 4 | 9 5 2 3 8 1 4 6 7 5 | 6 4 1 2 9 7 8 3 5 6 | 3 8 7 5 6 4 2 9 1 7 | 7 1 9 6 2 3 5 4 8 8 | 8 6 4 9 1 5 3 7 2 9 | 2 3 5 7 4 8 9 1 6 10 | -------------------------------------------------------------------------------- /ch05/noOK1.txt: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | 5 7 8 1 3 9 6 2 4 3 | 4 9 6 8 7 2 1 5 3 4 | 9 5 2 3 8 1 4 6 7 5 | 6 4 1 2 9 7 8 3 5 6 | 3 8 7 5 6 4 2 9 1 7 | 7 1 9 6 2 3 5 4 8 8 | 8 6 4 9 1 5 3 7 2 9 | 2 3 5 7 4 8 9 6 1 10 | -------------------------------------------------------------------------------- /ch06/manyInit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "a" 5 | "b" 6 | "fmt" 7 | ) 8 | 9 | func init() { 10 | fmt.Println("init() manyInit") 11 | } 12 | 13 | func main() { 14 | a.FromA() 15 | b.FromB() 16 | } 17 | -------------------------------------------------------------------------------- /ch06/useTwoVersions/useTwo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | v1 "github.com/mactsouk/myModule" 5 | v2 "github.com/mactsouk/myModule/v2" 6 | ) 7 | 8 | func main() { 9 | v1.Version() 10 | v2.Version() 11 | } 12 | -------------------------------------------------------------------------------- /ch02/callClib/callC.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "callC.h" 3 | 4 | void cHello() { 5 | printf("Hello from C!\n"); 6 | } 7 | 8 | void printMessage(char* message) { 9 | printf("Go send me %s\n", message); 10 | } -------------------------------------------------------------------------------- /ch06/useAPackage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "aPackage" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Using aPackage!") 10 | aPackage.A() 11 | aPackage.B() 12 | fmt.Println(aPackage.MyConstant) 13 | } 14 | -------------------------------------------------------------------------------- /ch02/justPanic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | if len(os.Args) == 1 { 10 | panic("Not enough arguments!") 11 | } 12 | 13 | fmt.Println("Thanks for the argument(s)!") 14 | } 15 | -------------------------------------------------------------------------------- /ch03/failMap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | var aMap map[string]int 10 | // aMap := map[string]int{} 11 | aMap = nil 12 | fmt.Println(aMap) 13 | aMap["test"] = 1 14 | 15 | } 16 | -------------------------------------------------------------------------------- /ch11/ex.go: -------------------------------------------------------------------------------- 1 | package ex 2 | 3 | func F1(n int) int { 4 | if n == 0 { 5 | return 0 6 | } 7 | if n == 1 || n == 2 { 8 | return 1 9 | } 10 | return F1(n-1) + F1(n-2) 11 | } 12 | 13 | func S1(s string) int { 14 | return len(s) 15 | } 16 | -------------------------------------------------------------------------------- /ch10/maxprocs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func getGOMAXPROCS() int { 9 | return runtime.GOMAXPROCS(0) 10 | } 11 | 12 | func main() { 13 | fmt.Printf("GOMAXPROCS: %d\n", getGOMAXPROCS()) 14 | } 15 | -------------------------------------------------------------------------------- /ch10/cloGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | for i := 0; i <= 20; i++ { 10 | go func() { 11 | fmt.Print(i, " ") 12 | }() 13 | } 14 | time.Sleep(time.Second) 15 | fmt.Println() 16 | } 17 | -------------------------------------------------------------------------------- /ch13/sharedRPC.go: -------------------------------------------------------------------------------- 1 | package sharedRPC 2 | 3 | type MyFloats struct { 4 | A1, A2 float64 5 | } 6 | 7 | type MyInterface interface { 8 | Multiply(arguments *MyFloats, reply *float64) error 9 | Power(arguments *MyFloats, reply *float64) error 10 | } 11 | -------------------------------------------------------------------------------- /ch06/ptrFun.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func getPtr(v *float64) float64 { 8 | return *v * *v 9 | } 10 | 11 | func main() { 12 | x := 12.2 13 | fmt.Println(getPtr(&x)) 14 | x = 12 15 | fmt.Println(getPtr(&x)) 16 | } 17 | -------------------------------------------------------------------------------- /ch11/quick.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func Add(x, y uint16) uint16 { 8 | var i uint16 9 | for i = 0; i < x; i++ { 10 | y++ 11 | } 12 | return y 13 | } 14 | 15 | func main() { 16 | fmt.Println(Add(0, 0)) 17 | } 18 | -------------------------------------------------------------------------------- /ch04/readMe.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"Mihalis", 3 | "Surname":"Tsoukalos", 4 | "Tel":[ 5 | {"Mobile":true,"Number":"1234-567"}, 6 | {"Mobile":true,"Number":"1234-abcd"}, 7 | {"Mobile":false,"Number":"abcc-567"} 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /ch08/viper/myJSONConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "item1": { 3 | "key1": "val1", 4 | "key2": false, 5 | "key3": "val3" 6 | }, 7 | "item2": { 8 | "key1": "val1", 9 | "key2": true, 10 | "key3": "val3" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /ch10/cloGoCorrect.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | for i := 0; i <= 20; i++ { 10 | i := i 11 | go func() { 12 | fmt.Print(i, " ") 13 | }() 14 | } 15 | time.Sleep(time.Second) 16 | fmt.Println() 17 | } 18 | -------------------------------------------------------------------------------- /ch11/xCompile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("You are using ", runtime.Compiler, " ") 10 | fmt.Println("on a", runtime.GOARCH, "machine") 11 | fmt.Println("with Go version", runtime.Version()) 12 | } 13 | -------------------------------------------------------------------------------- /ch06/returnPtr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func returnPtr(x int) *int { 8 | y := x * x 9 | return &y 10 | } 11 | 12 | func main() { 13 | sq := returnPtr(10) 14 | fmt.Println("sq value:", *sq) 15 | fmt.Println("sq memory address:", sq) 16 | } 17 | -------------------------------------------------------------------------------- /ch02/mapNoStar.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | ) 6 | 7 | func main() { 8 | var N = 40000000 9 | myMap := make(map[int]int) 10 | for i := 0; i < N; i++ { 11 | value := int(i) 12 | myMap[value] = value 13 | } 14 | runtime.GC() 15 | _ = myMap[0] 16 | } 17 | -------------------------------------------------------------------------------- /ch02/mapStar.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | ) 6 | 7 | func main() { 8 | var N = 40000000 9 | myMap := make(map[int]*int) 10 | for i := 0; i < N; i++ { 11 | value := int(i) 12 | myMap[value] = &value 13 | } 14 | runtime.GC() 15 | _ = myMap[0] 16 | } 17 | -------------------------------------------------------------------------------- /ch02/nodeTreeMore.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func functionOne(x int) { 8 | fmt.Println(x) 9 | } 10 | 11 | func main() { 12 | varOne := 1 13 | varTwo := 2 14 | fmt.Println("Hello there!") 15 | functionOne(varOne) 16 | functionOne(varTwo) 17 | } 18 | -------------------------------------------------------------------------------- /ch03/reslice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s1 := make([]int, 5) 7 | reSlice := s1[1:3] 8 | fmt.Println(s1) 9 | fmt.Println(reSlice) 10 | 11 | reSlice[0] = -100 12 | reSlice[1] = 123456 13 | fmt.Println(s1) 14 | fmt.Println(reSlice) 15 | } 16 | -------------------------------------------------------------------------------- /ch06/aPackage.go: -------------------------------------------------------------------------------- 1 | package aPackage 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func A() { 8 | fmt.Println("This is function A!") 9 | } 10 | 11 | func B() { 12 | fmt.Println("privateConstant:", privateConstant) 13 | } 14 | 15 | const MyConstant = 123 16 | const privateConstant = 21 17 | -------------------------------------------------------------------------------- /ch06/myModule/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /ch11/too_long.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | func sleep_with_me() { 8 | time.Sleep(5 * time.Second) 9 | } 10 | 11 | func get_one() int { 12 | return 1 13 | } 14 | 15 | func get_two() int { 16 | return 2 17 | } 18 | 19 | func main() { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ch01/stdIN.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | var f *os.File 11 | f = os.Stdin 12 | defer f.Close() 13 | 14 | scanner := bufio.NewScanner(f) 15 | for scanner.Scan() { 16 | fmt.Println(">", scanner.Text()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch02/cGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //#include 4 | //void callC() { 5 | // printf("Calling C code!\n"); 6 | //} 7 | import "C" 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println("A Go statement!") 12 | C.callC() 13 | fmt.Println("Another Go statement!") 14 | } 15 | -------------------------------------------------------------------------------- /ch05/dimensions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | array := [12][4][7][10]float64{} 9 | x := len(array) 10 | y := len(array[0]) 11 | z := len(array[0][0]) 12 | w := len(array[0][0][0]) 13 | fmt.Println("x:", x, "y:", y, "z:", z, "w:", w) 14 | } 15 | -------------------------------------------------------------------------------- /ch02/usedByC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | //export PrintMessage 10 | func PrintMessage() { 11 | fmt.Println("A Go function!") 12 | } 13 | 14 | //export Multiply 15 | func Multiply(a, b int) int { 16 | return a * b 17 | } 18 | 19 | func main() { 20 | } 21 | -------------------------------------------------------------------------------- /ch10/endlessComp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | var i byte 10 | go func() { 11 | for i = 0; i <= 255; i++ { 12 | } 13 | }() 14 | fmt.Println("Leaving goroutine!") 15 | runtime.Gosched() 16 | runtime.GC() 17 | 18 | fmt.Println("Good bye!") 19 | } 20 | -------------------------------------------------------------------------------- /ch09/writeCh.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeToChannel(c chan int, x int) { 9 | fmt.Println(x) 10 | c <- x 11 | close(c) 12 | fmt.Println(x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeToChannel(c, 10) 18 | time.Sleep(1 * time.Second) 19 | } 20 | -------------------------------------------------------------------------------- /ch11/ex_test.go: -------------------------------------------------------------------------------- 1 | package ex 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleF1() { 8 | fmt.Println(F1(10)) 9 | fmt.Println(F1(2)) 10 | // Output: 11 | // 55 12 | // 1 13 | } 14 | 15 | func ExampleS1() { 16 | fmt.Println(S1("123456789")) 17 | fmt.Println(S1("")) 18 | // Output: 19 | // 8 20 | // 0 21 | } 22 | -------------------------------------------------------------------------------- /ch02/willUseGo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "usedByC.h" 3 | 4 | int main(int argc, char **argv) { 5 | GoInt x = 12; 6 | GoInt y = 23; 7 | 8 | printf("About to call a Go function!\n"); 9 | PrintMessage(); 10 | GoInt p = Multiply(x,y); 11 | printf("Product: %d\n",(int)p); 12 | printf("It worked!\n"); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /ch11/documentMe_test.go: -------------------------------------------------------------------------------- 1 | package documentMe 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleS1() { 8 | fmt.Println(S1("123456789")) 9 | fmt.Println(S1("")) 10 | // Output: 11 | // 9 12 | // 0 13 | } 14 | 15 | func ExampleF1() { 16 | fmt.Println(F1(10)) 17 | fmt.Println(F1(2)) 18 | // Output: 19 | // 1 20 | // 55 21 | } 22 | -------------------------------------------------------------------------------- /ch12/gRPC/api.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package message_service; 4 | 5 | message Request { 6 | string text = 1; 7 | string subtext = 2; 8 | } 9 | 10 | message Response { 11 | string text = 1; 12 | string subtext = 2; 13 | } 14 | 15 | service MessageService { 16 | rpc SayIt (Request) returns (Response); 17 | } 18 | -------------------------------------------------------------------------------- /ch04/noStr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "John", 3 | "Surname": "Doe", 4 | "Age": 25, 5 | "Parents": [ 6 | "Jim", 7 | "Mary" 8 | ], 9 | "Tel":[ 10 | {"Mobile":true,"Number":"1234-567"}, 11 | {"Mobile":true,"Number":"1234-abcd"}, 12 | {"Mobile":false,"Number":"abcc-567"} 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /ch08/simpleFlag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | minusK := flag.Bool("k", true, "k flag") 10 | minusO := flag.Int("O", 1, "O") 11 | flag.Parse() 12 | 13 | valueK := *minusK 14 | valueO := *minusO 15 | valueO++ 16 | fmt.Println("-k:", valueK) 17 | fmt.Println("-O:", valueO) 18 | } 19 | -------------------------------------------------------------------------------- /ch04/unicode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode" 6 | ) 7 | 8 | func main() { 9 | const sL = "\x99\x00ab\x50\x00\x23\x50\x29\x9c" 10 | 11 | for i := 0; i < len(sL); i++ { 12 | if unicode.IsPrint(rune(sL[i])) { 13 | fmt.Printf("%c\n", sL[i]) 14 | } else { 15 | fmt.Println("Not printable!") 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch02/sliceGC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | ) 6 | 7 | type data struct { 8 | i, j int 9 | } 10 | 11 | func main() { 12 | var N = 40000000 13 | var structure []data 14 | for i := 0; i < N; i++ { 15 | value := int(i) 16 | structure = append(structure, data{value, value}) 17 | } 18 | 19 | runtime.GC() 20 | _ = structure[0] 21 | } 22 | -------------------------------------------------------------------------------- /ch01/stdOUT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | myString := "" 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | myString = "Please give me one argument!" 13 | } else { 14 | myString = arguments[1] 15 | } 16 | 17 | io.WriteString(os.Stdout, myString) 18 | io.WriteString(os.Stdout, "\n") 19 | } 20 | -------------------------------------------------------------------------------- /ch08/ids.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/user" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("User id:", os.Getuid()) 11 | 12 | var u *user.User 13 | u, _ = user.Current() 14 | fmt.Print("Group ids: ") 15 | groupIDs, _ := u.GroupIds() 16 | for _, i := range groupIDs { 17 | fmt.Print(i, " ") 18 | } 19 | fmt.Println() 20 | } 21 | -------------------------------------------------------------------------------- /ch01/logFatal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | ) 8 | 9 | func main() { 10 | sysLog, err := syslog.New(syslog.LOG_ALERT|syslog.LOG_MAIL, "Some program!") 11 | if err != nil { 12 | log.Fatal(err) 13 | } else { 14 | log.SetOutput(sysLog) 15 | } 16 | 17 | log.Fatal(sysLog) 18 | fmt.Println("Will you see this?") 19 | } 20 | -------------------------------------------------------------------------------- /ch01/logPanic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | ) 8 | 9 | func main() { 10 | sysLog, err := syslog.New(syslog.LOG_ALERT|syslog.LOG_MAIL, "Some program!") 11 | if err != nil { 12 | log.Fatal(err) 13 | } else { 14 | log.SetOutput(sysLog) 15 | } 16 | 17 | log.Panic(sysLog) 18 | fmt.Println("Will you see this?") 19 | } 20 | -------------------------------------------------------------------------------- /ch02/mapSplit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | ) 6 | 7 | func main() { 8 | var N = 40000000 9 | split := make([]map[int]int, 200) 10 | for i := range split { 11 | split[i] = make(map[int]int) 12 | } 13 | for i := 0; i < N; i++ { 14 | value := int(i) 15 | split[i%200][value] = value 16 | } 17 | runtime.GC() 18 | _ = split[0][0] 19 | } 20 | -------------------------------------------------------------------------------- /ch08/devRandom.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | f, err := os.Open("/dev/random") 11 | defer f.Close() 12 | 13 | if err != nil { 14 | fmt.Println(err) 15 | return 16 | } 17 | 18 | var seed int64 19 | binary.Read(f, binary.LittleEndian, &seed) 20 | fmt.Println("Seed:", seed) 21 | } 22 | -------------------------------------------------------------------------------- /ch09/simple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func function() { 9 | for i := 0; i < 10; i++ { 10 | fmt.Print(i) 11 | } 12 | } 13 | 14 | func main() { 15 | go function() 16 | 17 | go func() { 18 | for i := 10; i < 20; i++ { 19 | fmt.Print(i, " ") 20 | } 21 | }() 22 | 23 | time.Sleep(1 * time.Second) 24 | fmt.Println() 25 | } 26 | -------------------------------------------------------------------------------- /ch09/readClose.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | willClose := make(chan int, 10) 9 | // Write some data to the channel 10 | willClose <- -1 11 | willClose <- 0 12 | willClose <- 2 13 | // Empty channel 14 | <-willClose 15 | <-willClose 16 | <-willClose 17 | close(willClose) 18 | read := <-willClose 19 | fmt.Println(read) 20 | } 21 | -------------------------------------------------------------------------------- /ch11/cover/codeCover.go: -------------------------------------------------------------------------------- 1 | package codeCover 2 | 3 | func fibo1(n int) int { 4 | if n == 0 { 5 | return 0 6 | } else if n == 1 { 7 | return 1 8 | } else { 9 | return fibo1(n-1) + fibo1(n-2) 10 | } 11 | } 12 | 13 | func fibo2(n int) int { 14 | if n >= 0 { 15 | return 0 16 | } else if n == 1 { 17 | return 1 18 | } else { 19 | return fibo1(n-1) + fibo1(n-2) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch02/goEnv.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("You are using ", runtime.Compiler, " ") 10 | fmt.Println("on a", runtime.GOARCH, "machine") 11 | fmt.Println("Using Go version", runtime.Version()) 12 | fmt.Println("Number of CPUs:", runtime.NumCPU()) 13 | fmt.Println("Number of Goroutines:", runtime.NumGoroutine()) 14 | } 15 | -------------------------------------------------------------------------------- /ch08/permissions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | arguments := os.Args 10 | if len(arguments) == 1 { 11 | fmt.Printf("usage: permissions filename\n") 12 | return 13 | } 14 | 15 | filename := arguments[1] 16 | info, _ := os.Stat(filename) 17 | mode := info.Mode() 18 | fmt.Println(filename, "mode is", mode.String()[1:10]) 19 | } 20 | -------------------------------------------------------------------------------- /ch01/printing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | v1 := "123" 9 | v2 := 123 10 | v3 := "Have a nice day\n" 11 | v4 := "abc" 12 | 13 | fmt.Print(v1, v2, v3, v4) 14 | fmt.Println() 15 | fmt.Println(v1, v2, v3, v4) 16 | fmt.Print(v1, " ", v2, " ", v3, " ", v4, "\n") 17 | fmt.Printf("%s%d %s %s\n", v1, v2, v3, v4) 18 | } 19 | -------------------------------------------------------------------------------- /ch04/tuples.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func retThree(x int) (int, int, int) { 8 | return 2 * x, x * x, -x 9 | } 10 | 11 | func main() { 12 | fmt.Println(retThree(10)) 13 | n1, n2, n3 := retThree(20) 14 | fmt.Println(n1, n2, n3) 15 | 16 | n1, n2 = n2, n1 17 | fmt.Println(n1, n2, n3) 18 | 19 | x1, x2, x3 := n1*2, n1*n1, -n1 20 | fmt.Println(x1, x2, x3) 21 | } 22 | -------------------------------------------------------------------------------- /ch11/randomBuiltin.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "reflect" 7 | "testing/quick" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | type point3D struct { 13 | X, Y, Z int8 14 | S float32 15 | } 16 | ran := rand.New(rand.NewSource(time.Now().Unix())) 17 | 18 | myValues := reflect.TypeOf(point3D{}) 19 | x, _ := quick.Value(myValues, ran) 20 | fmt.Println(x) 21 | } 22 | -------------------------------------------------------------------------------- /ch13/HTTPS/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PARAMETERS----- 2 | BgUrgQQAIg== 3 | -----END EC PARAMETERS----- 4 | -----BEGIN EC PRIVATE KEY----- 5 | MIGkAgEBBDArwZ1yjzIWUh15Swtv6MSTAkVzDASfe6eHqfRkgo+2Rc/oDCKJrfiP 6 | gaXrpbGUOMWgBwYFK4EEACKhZANiAAShDVZ18ofoFgc0dPs4XivNybYlfwCrA08z 7 | VRT3MPxzRDs/iu49DAzTWe2Pl0SWke+HtgUBX9r9kE5UKuVcO532q5Coz1mWi5sZ 8 | lThl8q6JswunvZiuFqrUL9jYgtzGAmk= 9 | -----END EC PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /ch11/cannotReach.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func f1() int { 8 | fmt.Println("Entering f1()") 9 | return -10 10 | fmt.Println("Exiting f1()") 11 | return -1 12 | } 13 | 14 | func f2() int { 15 | if true { 16 | return 10 17 | } 18 | fmt.Println("Exiting f2()") 19 | return 0 20 | } 21 | 22 | func main() { 23 | fmt.Println(f1()) 24 | fmt.Println("Exiting program...") 25 | } 26 | -------------------------------------------------------------------------------- /ch03/appendArrayToSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | s := []int{1, 2, 3} 9 | a := [3]int{4, 5, 6} 10 | 11 | ref := a[:] 12 | fmt.Println("Existing array:\t", ref) 13 | t := append(s, ref...) 14 | fmt.Println("New slice:\t", t) 15 | s = append(s, ref...) 16 | fmt.Println("Existing slice:\t", s) 17 | 18 | s = append(s, s...) 19 | fmt.Println("s+s:\t\t", s) 20 | } 21 | -------------------------------------------------------------------------------- /ch02/unsafe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var value int64 = 5 10 | var p1 = &value 11 | var p2 = (*int32)(unsafe.Pointer(p1)) 12 | 13 | fmt.Println("*p1: ", *p1) 14 | fmt.Println("*p2: ", *p2) 15 | *p1 = 5434123412312431212 16 | fmt.Println(value) 17 | fmt.Println("*p2: ", *p2) 18 | *p1 = 54341234 19 | fmt.Println(value) 20 | fmt.Println("*p2: ", *p2) 21 | } 22 | -------------------------------------------------------------------------------- /ch06/returnFunction.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func funReturnFun() func() int { 8 | i := 0 9 | return func() int { 10 | i++ 11 | return i * i 12 | } 13 | } 14 | 15 | func main() { 16 | i := funReturnFun() 17 | j := funReturnFun() 18 | 19 | fmt.Println("1:", i()) 20 | fmt.Println("2:", i()) 21 | fmt.Println("j1:", j()) 22 | fmt.Println("j2:", j()) 23 | fmt.Println("3:", i()) 24 | } 25 | -------------------------------------------------------------------------------- /ch10/forgetMutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var m sync.Mutex 9 | 10 | func function() { 11 | m.Lock() 12 | fmt.Println("Locked!") 13 | } 14 | 15 | func main() { 16 | var w sync.WaitGroup 17 | 18 | go func() { 19 | defer w.Done() 20 | function() 21 | }() 22 | w.Add(1) 23 | 24 | go func() { 25 | defer w.Done() 26 | function() 27 | }() 28 | w.Add(1) 29 | 30 | w.Wait() 31 | } 32 | -------------------------------------------------------------------------------- /ch03/mapNoStarTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | var N = 40000000 11 | myMap := make(map[int]int) 12 | 13 | for i := 0; i < N; i++ { 14 | value := int(i) 15 | myMap[value] = value 16 | } 17 | 18 | start := time.Now() 19 | runtime.GC() 20 | duration := time.Since(start) 21 | fmt.Println("It took GC()", duration, "to finish") 22 | 23 | _ = myMap[0] 24 | } 25 | -------------------------------------------------------------------------------- /ch03/mapStarTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | var N = 40000000 11 | myMap := make(map[int]*int) 12 | 13 | for i := 0; i < N; i++ { 14 | value := int(i) 15 | myMap[value] = &value 16 | } 17 | 18 | start := time.Now() 19 | runtime.GC() 20 | duration := time.Since(start) 21 | fmt.Println("It took GC()", duration, "to finish") 22 | 23 | _ = myMap[0] 24 | } 25 | -------------------------------------------------------------------------------- /ch09/create.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | n := flag.Int("n", 10, "Number of goroutines") 11 | flag.Parse() 12 | 13 | count := *n 14 | fmt.Printf("Going to create %d goroutines.\n", count) 15 | for i := 0; i < count; i++ { 16 | go func(x int) { 17 | fmt.Printf("%d ", x) 18 | }(i) 19 | } 20 | 21 | time.Sleep(time.Second) 22 | fmt.Println("\nExiting...") 23 | } 24 | -------------------------------------------------------------------------------- /ch12/MXrecords.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Need a domain name!") 13 | return 14 | } 15 | 16 | domain := arguments[1] 17 | MXs, err := net.LookupMX(domain) 18 | if err != nil { 19 | fmt.Println(err) 20 | return 21 | } 22 | 23 | for _, MX := range MXs { 24 | fmt.Println(MX.Host) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch12/NSrecords.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Need a domain name!") 13 | return 14 | } 15 | 16 | domain := arguments[1] 17 | NSs, err := net.LookupNS(domain) 18 | if err != nil { 19 | fmt.Println(err) 20 | return 21 | } 22 | 23 | for _, NS := range NSs { 24 | fmt.Println(NS.Host) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch07/ooo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type a struct { 8 | XX int 9 | YY int 10 | } 11 | 12 | type b struct { 13 | AA string 14 | XX int 15 | } 16 | 17 | type c struct { 18 | A a 19 | B b 20 | } 21 | 22 | func (A a) A() { 23 | fmt.Println("Function A() for A") 24 | } 25 | 26 | func (B b) A() { 27 | fmt.Println("Function A() for B") 28 | } 29 | 30 | func main() { 31 | var i c 32 | i.A.A() 33 | i.B.A() 34 | } 35 | -------------------------------------------------------------------------------- /ch07/debug/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func function(i int) int { 9 | return i * i 10 | } 11 | 12 | func main() { 13 | if len(os.Args) == 1 { 14 | fmt.Println("Need at least one argument.") 15 | return 16 | } 17 | 18 | i := 5 19 | fmt.Println("Debugging with Delve") 20 | fmt.Println(i) 21 | fmt.Println(function(i)) 22 | 23 | for arg, _ := range os.Args[1:] { 24 | fmt.Println(arg) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch04/data.xml: -------------------------------------------------------------------------------- 1 | xmlData: 2 | 3 | Dimitris 4 | Tsoukalos 5 | 6 | true 7 | 1234-567 8 | 9 | 10 | true 11 | 1234-abcd 12 | 13 | 14 | false 15 | abcc-567 16 | 17 | 18 | -------------------------------------------------------------------------------- /ch04/logEntries.txt: -------------------------------------------------------------------------------- 1 | - - [21/Nov/2017:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 2188249 "-" 2 | - - [21/Jun/2017:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 3 | - - [25/Lun/2017:20:05:34 +0200] "GET /MongoDjango.zip HTTP/1.1" 200 118362 4 | - - [Jun-21-17:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 5 | - - [20/Nov/2017:20:05:34 +0200] "GET /MongoDjango.zip HTTP/1.1" 200 118362 6 | - - [35/Nov/2017:20:05:34 +0200] "GET MongoDjango.zip HTTP/1.1" 200 118362 7 | -------------------------------------------------------------------------------- /ch01/stdERR.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | myString := "" 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | myString = "Please give me one argument!" 13 | } else { 14 | myString = arguments[1] 15 | } 16 | 17 | io.WriteString(os.Stdout, "This is Standard output\n") 18 | io.WriteString(os.Stderr, myString) 19 | io.WriteString(os.Stderr, "\n") 20 | } 21 | -------------------------------------------------------------------------------- /ch06/funFun.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func function1(i int) int { 6 | return i + i 7 | } 8 | 9 | func function2(i int) int { 10 | return i * i 11 | } 12 | 13 | func funFun(f func(int) int, v int) int { 14 | return f(v) 15 | } 16 | 17 | func main() { 18 | fmt.Println("function1:", funFun(function1, 123)) 19 | fmt.Println("function2:", funFun(function2, 123)) 20 | fmt.Println("Inline", funFun(func(i int) int { return i * i * i }, 123)) 21 | } 22 | -------------------------------------------------------------------------------- /ch07/assertion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var myInt interface{} = 123 9 | 10 | k, ok := myInt.(int) 11 | if ok { 12 | fmt.Println("Success:", k) 13 | } 14 | 15 | v, ok := myInt.(float64) 16 | if ok { 17 | fmt.Println(v) 18 | } else { 19 | fmt.Println("Failed without panicking!") 20 | } 21 | 22 | i := myInt.(int) 23 | fmt.Println("No checking:", i) 24 | 25 | j := myInt.(bool) 26 | fmt.Println(j) 27 | } 28 | -------------------------------------------------------------------------------- /ch04/structures.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | type XYZ struct { 10 | X int 11 | Y int 12 | Z int 13 | } 14 | 15 | var s1 XYZ 16 | fmt.Println(s1.Y, s1.Z) 17 | 18 | p1 := XYZ{23, 12, -2} 19 | p2 := XYZ{Z: 12, Y: 13} 20 | fmt.Println(p1) 21 | fmt.Println(p2) 22 | 23 | pSlice := [4]XYZ{} 24 | pSlice[2] = p1 25 | pSlice[0] = p2 26 | fmt.Println(pSlice) 27 | p2 = XYZ{1, 2, 3} 28 | fmt.Println(pSlice) 29 | } 30 | -------------------------------------------------------------------------------- /ch03/parseTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | var myTime string 12 | if len(os.Args) != 2 { 13 | fmt.Printf("usage: %s string\n", filepath.Base(os.Args[0])) 14 | os.Exit(1) 15 | } 16 | 17 | myTime = os.Args[1] 18 | d, err := time.Parse("15:04", myTime) 19 | if err == nil { 20 | fmt.Println("Full:", d) 21 | fmt.Println("Time:", d.Hour(), d.Minute()) 22 | } else { 23 | fmt.Println(err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch12/netCapabilities.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | interfaces, err := net.Interfaces() 10 | 11 | if err != nil { 12 | fmt.Print(err) 13 | return 14 | } 15 | 16 | for _, i := range interfaces { 17 | fmt.Printf("Name : %v\n", i.Name) 18 | fmt.Println("Interface Flags:", i.Flags.String()) 19 | fmt.Println("Interface MTU:", i.MTU) 20 | fmt.Println("Interface Hardware Address:", i.HardwareAddr) 21 | 22 | fmt.Println() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ch03/sliceGCTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | type data struct { 10 | i, j int 11 | } 12 | 13 | func main() { 14 | var N = 40000000 15 | var structure []data 16 | 17 | for i := 0; i < N; i++ { 18 | value := int(i) 19 | structure = append(structure, data{value, value}) 20 | } 21 | 22 | start := time.Now() 23 | runtime.GC() 24 | duration := time.Since(start) 25 | 26 | fmt.Println("It took GC()", duration, "to finish") 27 | _ = structure[0] 28 | } 29 | -------------------------------------------------------------------------------- /ch10/bufChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | numbers := make(chan int, 5) 9 | counter := 10 10 | 11 | for i := 0; i < counter; i++ { 12 | select { 13 | case numbers <- i: 14 | default: 15 | fmt.Println("Not enough space for", i) 16 | } 17 | } 18 | 19 | for i := 0; i < counter+5; i++ { 20 | select { 21 | case num := <-numbers: 22 | fmt.Println(num) 23 | default: 24 | fmt.Println("Nothing more to be done!") 25 | break 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch12/home.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 |

Welcome to the Go KV store!

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ch03/parseDate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | 12 | var myDate string 13 | if len(os.Args) != 2 { 14 | fmt.Printf("usage: %s string\n", filepath.Base(os.Args[0])) 15 | return 16 | } 17 | 18 | myDate = os.Args[1] 19 | d, err := time.Parse("02 January 2006", myDate) 20 | if err == nil { 21 | fmt.Println("Full:", d) 22 | fmt.Println("Time:", d.Day(), d.Month(), d.Year()) 23 | } else { 24 | fmt.Println(err) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch08/cobra/aliases/cmd/preferences.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var preferencesCmd = &cobra.Command{ 9 | Use: "preferences", 10 | Aliases: []string{"prefer", "pref", "prf"}, 11 | Short: "A brief description of your command", 12 | Long: `A longer description of your command`, 13 | Run: func(cmd *cobra.Command, args []string) { 14 | fmt.Println("preferences called") 15 | }, 16 | } 17 | 18 | func init() { 19 | rootCmd.AddCommand(preferencesCmd) 20 | } 21 | -------------------------------------------------------------------------------- /ch02/requiredVersion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | myVersion := runtime.Version() 12 | major := strings.Split(myVersion, ".")[0][2] 13 | minor := strings.Split(myVersion, ".")[1] 14 | m1, _ := strconv.Atoi(string(major)) 15 | m2, _ := strconv.Atoi(minor) 16 | 17 | if m1 == 1 && m2 < 8 { 18 | fmt.Println("Need Go version 1.8 or higher!") 19 | return 20 | } 21 | 22 | fmt.Println("You are using Go version 1.8 or higher!") 23 | } 24 | -------------------------------------------------------------------------------- /ch13/HTTPS/https.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | var PORT = ":1443" 9 | 10 | func Default(w http.ResponseWriter, req *http.Request) { 11 | fmt.Fprintf(w, "This is an example HTTPS server!\n") 12 | } 13 | 14 | func main() { 15 | http.HandleFunc("/", Default) 16 | fmt.Println("Listening to port number", PORT) 17 | 18 | err := http.ListenAndServeTLS(PORT, "server.crt", "server.key", nil) 19 | if err != nil { 20 | fmt.Println("ListenAndServeTLS: ", err) 21 | return 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch02/defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func d1() { 8 | for i := 3; i > 0; i-- { 9 | defer fmt.Print(i, " ") 10 | } 11 | } 12 | 13 | func d2() { 14 | for i := 3; i > 0; i-- { 15 | defer func() { 16 | fmt.Print(i, " ") 17 | }() 18 | } 19 | fmt.Println() 20 | } 21 | 22 | func d3() { 23 | for i := 3; i > 0; i-- { 24 | defer func(n int) { 25 | fmt.Print(n, " ") 26 | }(i) 27 | } 28 | } 29 | 30 | func main() { 31 | d1() 32 | d2() 33 | fmt.Println() 34 | d3() 35 | fmt.Println() 36 | } 37 | -------------------------------------------------------------------------------- /ch03/mapSplitTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | var N = 40000000 11 | split := make([]map[int]int, 200) 12 | 13 | for i := range split { 14 | split[i] = make(map[int]int) 15 | } 16 | 17 | for i := 0; i < N; i++ { 18 | value := int(i) 19 | split[i%200][value] = value 20 | } 21 | 22 | start := time.Now() 23 | runtime.GC() 24 | duration := time.Since(start) 25 | fmt.Println("It took GC()", duration, "to finish") 26 | 27 | _ = split[0][0] 28 | } 29 | -------------------------------------------------------------------------------- /ch04/runes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | const r1 = '€' 9 | fmt.Println("(int32) r1:", r1) 10 | fmt.Printf("(HEX) r1: %x\n", r1) 11 | fmt.Printf("(as a String) r1: %s\n", r1) 12 | fmt.Printf("(as a character) r1: %c\n", r1) 13 | 14 | fmt.Println("A string is a collection of runes:", []byte("Mihalis")) 15 | aString := []byte("Mihalis") 16 | for x, y := range aString { 17 | fmt.Println(x, y) 18 | fmt.Printf("Char: %c\n", aString[x]) 19 | } 20 | fmt.Printf("%s\n", aString) 21 | } 22 | -------------------------------------------------------------------------------- /ch08/cobra/aliases/cmd/initialization.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var initializationCmd = &cobra.Command{ 9 | Use: "initialization", 10 | Aliases: []string{"initialize", "init"}, 11 | Short: "A brief description of your command", 12 | Long: `A longer description of your command`, 13 | Run: func(cmd *cobra.Command, args []string) { 14 | fmt.Println("initialization called") 15 | }, 16 | } 17 | 18 | func init() { 19 | rootCmd.AddCommand(initializationCmd) 20 | } 21 | -------------------------------------------------------------------------------- /ch08/viper/useViper.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/viper" 6 | ) 7 | 8 | func main() { 9 | viper.BindEnv("GOMAXPROCS") 10 | val := viper.Get("GOMAXPROCS") 11 | fmt.Println("GOMAXPROCS:", val) 12 | viper.Set("GOMAXPROCS", 10) 13 | val = viper.Get("GOMAXPROCS") 14 | fmt.Println("GOMAXPROCS:", val) 15 | 16 | viper.BindEnv("NEW_VARIABLE") 17 | val = viper.Get("NEW_VARIABLE") 18 | if val == nil { 19 | fmt.Println("NEW_VARIABLE not defined.") 20 | return 21 | } 22 | fmt.Println(val) 23 | } 24 | -------------------------------------------------------------------------------- /ch09/readCh.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeToChannel(c chan int, x int) { 9 | fmt.Println("1", x) 10 | c <- x 11 | close(c) 12 | fmt.Println("2", x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeToChannel(c, 10) 18 | time.Sleep(1 * time.Second) 19 | fmt.Println("Read:", <-c) 20 | time.Sleep(1 * time.Second) 21 | 22 | _, ok := <-c 23 | if ok { 24 | fmt.Println("Channel is open!") 25 | } else { 26 | fmt.Println("Channel is closed!") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch11/testMe.go: -------------------------------------------------------------------------------- 1 | package testMe 2 | 3 | func f1(n int) int { 4 | if n == 0 { 5 | return 0 6 | } 7 | if n == 1 { 8 | return 1 9 | } 10 | return f1(n-1) + f1(n-2) 11 | } 12 | 13 | func f2(n int) int { 14 | if n == 0 { 15 | return 0 16 | } 17 | if n == 1 { 18 | return 2 19 | } 20 | 21 | return f2(n-1) + f2(n-2) 22 | } 23 | 24 | func s1(s string) int { 25 | if s == "" { 26 | return 0 27 | } 28 | n := 1 29 | for range s { 30 | n++ 31 | } 32 | return n 33 | } 34 | 35 | func s2(s string) int { 36 | return len(s) 37 | } 38 | -------------------------------------------------------------------------------- /ch13/lowLevel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | netaddr, err := net.ResolveIPAddr("ip4", "127.0.0.1") 10 | if err != nil { 11 | fmt.Println(err) 12 | return 13 | } 14 | conn, err := net.ListenIP("ip4:icmp", netaddr) 15 | if err != nil { 16 | fmt.Println(err) 17 | return 18 | } 19 | 20 | buffer := make([]byte, 1024) 21 | n, _, err := conn.ReadFrom(buffer) 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | fmt.Printf("% X\n", buffer[0:n]) 28 | } 29 | -------------------------------------------------------------------------------- /ch13/HTTPS/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBRTCBzQIJAIqTLJdBypljMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAkdSMB4X 3 | DTE5MDUxNjA2NDIzMloXDTI5MDUxMzA2NDIzMlowDTELMAkGA1UEBhMCR1IwdjAQ 4 | BgcqhkjOPQIBBgUrgQQAIgNiAAShDVZ18ofoFgc0dPs4XivNybYlfwCrA08zVRT3 5 | MPxzRDs/iu49DAzTWe2Pl0SWke+HtgUBX9r9kE5UKuVcO532q5Coz1mWi5sZlThl 6 | 8q6JswunvZiuFqrUL9jYgtzGAmkwCgYIKoZIzj0EAwIDZwAwZAIwNPkVnuGHxubM 7 | k5CkmAXRxgof841XP2yGyetRK/AVLYCopXWYDTvjw/DL7bKcaMSdAjB2uo/8boWV 8 | oQSFEHiz0jH35TlDzxxIMrlZCioqsgq5+/bl+85q+NY+uj4zm6mVSq0= 9 | -----END CERTIFICATE----- 10 | -------------------------------------------------------------------------------- /ch07/methods.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type twoInts struct { 8 | X int64 9 | Y int64 10 | } 11 | 12 | func regularFunction(a, b twoInts) twoInts { 13 | temp := twoInts{X: a.X + b.X, Y: a.Y + b.Y} 14 | return temp 15 | } 16 | 17 | func (a twoInts) method(b twoInts) twoInts { 18 | temp := twoInts{X: a.X + b.X, Y: a.Y + b.Y} 19 | return temp 20 | } 21 | 22 | func main() { 23 | i := twoInts{X: 1, Y: 2} 24 | j := twoInts{X: -5, Y: -2} 25 | fmt.Println(regularFunction(i, j)) 26 | fmt.Println(i.method(j)) 27 | } 28 | -------------------------------------------------------------------------------- /ch02/callC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // #cgo CFLAGS: -I${SRCDIR}/callClib 4 | // #cgo LDFLAGS: ${SRCDIR}/callC.a 5 | // #include 6 | // #include 7 | import "C" 8 | 9 | import ( 10 | "fmt" 11 | "unsafe" 12 | ) 13 | 14 | func main() { 15 | fmt.Println("Going to call a C function!") 16 | C.cHello() 17 | 18 | fmt.Println("Going to call another C function!") 19 | myMessage := C.CString("This is Mihalis!") 20 | defer C.free(unsafe.Pointer(myMessage)) 21 | C.printMessage(myMessage) 22 | 23 | fmt.Println("All perfectly done!") 24 | } 25 | -------------------------------------------------------------------------------- /ch02/panicRecover.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func a() { 8 | fmt.Println("Inside a()") 9 | defer func() { 10 | if c := recover(); c != nil { 11 | fmt.Println("Recover inside a()!") 12 | } 13 | }() 14 | fmt.Println("About to call b()") 15 | b() 16 | fmt.Println("b() exited!") 17 | fmt.Println("Exiting a().") 18 | } 19 | 20 | func b() { 21 | fmt.Println("Inside b()") 22 | panic("Panic in b()!") 23 | fmt.Println("Exiting b()") 24 | } 25 | 26 | func main() { 27 | a() 28 | fmt.Println("main() ended!") 29 | } 30 | -------------------------------------------------------------------------------- /ch06/useSyscall.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "syscall" 7 | ) 8 | 9 | func main() { 10 | pid, _, _ := syscall.Syscall(39, 0, 0, 0) 11 | fmt.Println("My pid is", pid) 12 | uid, _, _ := syscall.Syscall(24, 0, 0, 0) 13 | fmt.Println("User ID:", uid) 14 | 15 | message := []byte{'H', 'e', 'l', 'l', 'o', '!', '\n'} 16 | fd := 1 17 | syscall.Write(fd, message) 18 | 19 | fmt.Println("Using syscall.Exec()") 20 | command := "/bin/ls" 21 | env := os.Environ() 22 | syscall.Exec(command, []string{"ls", "-a", "-x"}, env) 23 | } 24 | -------------------------------------------------------------------------------- /ch07/goCoIn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type first struct{} 8 | 9 | func (a first) F() { 10 | a.shared() 11 | } 12 | 13 | func (a first) shared() { 14 | fmt.Println("This is shared() from first!") 15 | } 16 | 17 | type second struct { 18 | first 19 | } 20 | 21 | func (a second) shared() { 22 | fmt.Println("This is shared() from second!") 23 | } 24 | 25 | func main() { 26 | first{}.F() 27 | second{}.shared() 28 | i := second{} 29 | j := i.first 30 | j.F() 31 | // (i.first).F() 32 | // (second{}.first).F() 33 | } 34 | -------------------------------------------------------------------------------- /ch10/nilChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func add(c chan int) { 10 | sum := 0 11 | t := time.NewTimer(time.Second) 12 | 13 | for { 14 | select { 15 | case input := <-c: 16 | sum = sum + input 17 | case <-t.C: 18 | c = nil 19 | fmt.Println(sum) 20 | } 21 | } 22 | } 23 | 24 | func send(c chan int) { 25 | for { 26 | c <- rand.Intn(10) 27 | } 28 | } 29 | 30 | func main() { 31 | c := make(chan int) 32 | go add(c) 33 | go send(c) 34 | 35 | time.Sleep(3 * time.Second) 36 | } 37 | -------------------------------------------------------------------------------- /ch12/webClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 14 | return 15 | } 16 | 17 | URL := os.Args[1] 18 | data, err := http.Get(URL) 19 | 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } else { 24 | defer data.Body.Close() 25 | _, err := io.Copy(os.Stdout, data.Body) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch03/usingTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Epoch time:", time.Now().Unix()) 10 | t := time.Now() 11 | fmt.Println(t, t.Format(time.RFC3339)) 12 | fmt.Println(t.Weekday(), t.Day(), t.Month(), t.Year()) 13 | 14 | time.Sleep(time.Second) 15 | t1 := time.Now() 16 | fmt.Println("Time difference:", t1.Sub(t)) 17 | 18 | formatT := t.Format("01 January 2006") 19 | fmt.Println(formatT) 20 | loc, _ := time.LoadLocation("Europe/Paris") 21 | londonTime := t.In(loc) 22 | fmt.Println("Paris:", londonTime) 23 | } 24 | -------------------------------------------------------------------------------- /ch01/customLog.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | var LOGFILE = "/tmp/mGo.log" 10 | 11 | func main() { 12 | f, err := os.OpenFile(LOGFILE, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 13 | 14 | if err != nil { 15 | fmt.Println(err) 16 | return 17 | } 18 | defer f.Close() 19 | 20 | // LstdFlags = Ldate | Ltime 21 | // initial values for the standard logger 22 | iLog := log.New(f, "customLog ", log.LstdFlags) 23 | iLog.Println("Hello there!") 24 | iLog.Println("Another log entry!") 25 | } 26 | -------------------------------------------------------------------------------- /ch12/netConfig.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | interfaces, err := net.Interfaces() 10 | if err != nil { 11 | fmt.Println(err) 12 | return 13 | } 14 | 15 | for _, i := range interfaces { 16 | fmt.Printf("Interface: %v\n", i.Name) 17 | byName, err := net.InterfaceByName(i.Name) 18 | if err != nil { 19 | fmt.Println(err) 20 | } 21 | 22 | addresses, err := byName.Addrs() 23 | for k, v := range addresses { 24 | fmt.Printf("Interface Address #%v : %v\n", k, v.String()) 25 | } 26 | fmt.Println() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch09/syncGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "sync" 7 | ) 8 | 9 | func main() { 10 | n := flag.Int("n", 20, "Number of goroutines") 11 | flag.Parse() 12 | count := *n 13 | fmt.Printf("Going to create %d goroutines.\n", count) 14 | 15 | var waitGroup sync.WaitGroup 16 | fmt.Printf("%#v\n", waitGroup) 17 | for i := 0; i < count; i++ { 18 | waitGroup.Add(1) 19 | go func(x int) { 20 | defer waitGroup.Done() 21 | fmt.Printf("%d ", x) 22 | }(i) 23 | } 24 | 25 | fmt.Printf("%#v\n", waitGroup) 26 | waitGroup.Wait() 27 | fmt.Println("\nExiting...") 28 | } 29 | -------------------------------------------------------------------------------- /ch11/too_long_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_test_one(t *testing.T) { 8 | sleep_with_me() 9 | value := get_one() 10 | if value != 1 { 11 | t.Errorf("Function returned %v", value) 12 | } 13 | sleep_with_me() 14 | } 15 | 16 | func Test_test_two(t *testing.T) { 17 | sleep_with_me() 18 | value := get_two() 19 | if value != 2 { 20 | t.Errorf("Function returned %v", value) 21 | } 22 | } 23 | 24 | func Test_that_will_fail(t *testing.T) { 25 | value := get_one() 26 | if value != 2 { 27 | t.Errorf("Function returned %v", value) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch11/cover/codeCover_test.go: -------------------------------------------------------------------------------- 1 | package codeCover 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFibo1(t *testing.T) { 8 | if fibo1(1) != 1 { 9 | t.Errorf("Error fibo1(1): %d\n", fibo1(1)) 10 | } 11 | } 12 | 13 | func TestFibo2(t *testing.T) { 14 | if fibo2(0) != 0 { 15 | t.Errorf("Error fibo2(0): %d\n", fibo1(0)) 16 | } 17 | } 18 | 19 | func TestFibo1_10(t *testing.T) { 20 | if fibo1(10) == 1 { 21 | t.Errorf("Error fibo1(1): %d\n", fibo1(1)) 22 | } 23 | } 24 | 25 | func TestFibo2_10(t *testing.T) { 26 | if fibo2(10) != 0 { 27 | t.Errorf("Error fibo2(0): %d\n", fibo1(0)) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch01/cla.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) == 1 { 11 | fmt.Println("Please give one or more floats.") 12 | os.Exit(1) 13 | } 14 | 15 | arguments := os.Args 16 | min, _ := strconv.ParseFloat(arguments[1], 64) 17 | max, _ := strconv.ParseFloat(arguments[1], 64) 18 | 19 | for i := 2; i < len(arguments); i++ { 20 | n, _ := strconv.ParseFloat(arguments[i], 64) 21 | if n < min { 22 | min = n 23 | } 24 | if n > max { 25 | max = n 26 | } 27 | } 28 | 29 | fmt.Println("Min:", min) 30 | fmt.Println("Max:", max) 31 | } 32 | -------------------------------------------------------------------------------- /ch10/moreContext.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | type aKey string 9 | 10 | func searchKey(ctx context.Context, k aKey) { 11 | v := ctx.Value(k) 12 | if v != nil { 13 | fmt.Println("found value:", v) 14 | return 15 | } else { 16 | fmt.Println("key not found:", k) 17 | } 18 | } 19 | 20 | func main() { 21 | myKey := aKey("mySecretValue") 22 | ctx := context.WithValue(context.Background(), myKey, "mySecretValue") 23 | 24 | searchKey(ctx, myKey) 25 | 26 | searchKey(ctx, aKey("notThere")) 27 | emptyCtx := context.TODO() 28 | searchKey(emptyCtx, aKey("notThere")) 29 | } 30 | -------------------------------------------------------------------------------- /ch08/viper/flagToViper.go: -------------------------------------------------------------------------------- 1 | // package main 2 | // 3 | // import ( 4 | // "flag" 5 | // "fmt" 6 | // ) 7 | // 8 | // func main() { 9 | // minusI := flag.Int("i", 100, "i parameter") 10 | // flag.Parse() 11 | // i := *minusI 12 | // fmt.Println(i) 13 | // } 14 | 15 | package main 16 | 17 | import ( 18 | "flag" 19 | "fmt" 20 | "github.com/spf13/pflag" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | func main() { 25 | flag.Int("i", 100, "i parameter") 26 | pflag.CommandLine.AddGoFlagSet(flag.CommandLine) 27 | pflag.Parse() 28 | viper.BindPFlags(pflag.CommandLine) 29 | i := viper.GetInt("i") 30 | fmt.Println(i) 31 | } 32 | -------------------------------------------------------------------------------- /ch03/pointers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func getPointer(n *int) { 8 | *n = *n * *n 9 | } 10 | 11 | func returnPointer(n int) *int { 12 | v := n * n 13 | return &v 14 | } 15 | 16 | func main() { 17 | i := -10 18 | j := 25 19 | 20 | pI := &i 21 | pJ := &j 22 | 23 | fmt.Println("pI memory:", pI) 24 | fmt.Println("pJ memory:", pJ) 25 | fmt.Println("pI value:", *pI) 26 | fmt.Println("pJ value:", *pJ) 27 | 28 | *pI = 123456 29 | *pI-- 30 | fmt.Println("i:", i) 31 | 32 | getPointer(pJ) 33 | fmt.Println("j:", j) 34 | k := returnPointer(12) 35 | fmt.Println(*k) 36 | fmt.Println(k) 37 | } 38 | -------------------------------------------------------------------------------- /ch04/parsingJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a filename!") 14 | return 15 | } 16 | 17 | filename := arguments[1] 18 | 19 | fileData, err := ioutil.ReadFile(filename) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | var parsedData map[string]interface{} 26 | json.Unmarshal([]byte(fileData), &parsedData) 27 | 28 | for key, value := range parsedData { 29 | fmt.Println("key:", key, "value:", value) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch10/defineOrder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func A(a, b chan struct{}) { 9 | <-a 10 | fmt.Println("A()!") 11 | time.Sleep(time.Second) 12 | close(b) 13 | } 14 | 15 | func B(a, b chan struct{}) { 16 | <-a 17 | fmt.Println("B()!") 18 | close(b) 19 | } 20 | 21 | func C(a chan struct{}) { 22 | <-a 23 | fmt.Println("C()!") 24 | } 25 | 26 | func main() { 27 | x := make(chan struct{}) 28 | y := make(chan struct{}) 29 | z := make(chan struct{}) 30 | 31 | go C(z) 32 | go A(x, y) 33 | go C(z) 34 | go B(y, z) 35 | go C(z) 36 | 37 | close(x) 38 | time.Sleep(3 * time.Second) 39 | } 40 | -------------------------------------------------------------------------------- /ch10/timeOut1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | c1 := make(chan string) 10 | go func() { 11 | time.Sleep(time.Second * 3) 12 | c1 <- "c1 OK" 13 | }() 14 | 15 | select { 16 | case res := <-c1: 17 | fmt.Println(res) 18 | case <-time.After(time.Second * 1): 19 | fmt.Println("timeout c1") 20 | } 21 | 22 | c2 := make(chan string) 23 | go func() { 24 | time.Sleep(3 * time.Second) 25 | c2 <- "c2 OK" 26 | }() 27 | 28 | select { 29 | case res := <-c2: 30 | fmt.Println(res) 31 | case <-time.After(4 * time.Second): 32 | fmt.Println("timeout c2") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch05/conRing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/ring" 5 | "fmt" 6 | ) 7 | 8 | var size int = 10 9 | 10 | func main() { 11 | myRing := ring.New(size + 1) 12 | fmt.Println("Empty ring:", *myRing) 13 | 14 | for i := 0; i < myRing.Len()-1; i++ { 15 | myRing.Value = i 16 | myRing = myRing.Next() 17 | } 18 | 19 | myRing.Value = 2 20 | 21 | sum := 0 22 | myRing.Do(func(x interface{}) { 23 | t := x.(int) 24 | sum = sum + t 25 | }) 26 | fmt.Println("Sum:", sum) 27 | 28 | for i := 0; i < myRing.Len()+2; i++ { 29 | myRing = myRing.Next() 30 | fmt.Print(myRing.Value, " ") 31 | } 32 | fmt.Println() 33 | } 34 | -------------------------------------------------------------------------------- /ch06/variadic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func varFunc(input ...string) { 9 | fmt.Println(input) 10 | } 11 | 12 | func oneByOne(message string, s ...int) int { 13 | fmt.Println(message) 14 | sum := 0 15 | for i, a := range s { 16 | fmt.Println(i, a) 17 | sum = sum + a 18 | } 19 | s[0] = -1000 20 | return sum 21 | } 22 | 23 | func main() { 24 | arguments := os.Args 25 | varFunc(arguments...) 26 | sum := oneByOne("Adding numbers...", 1, 2, 3, 4, 5, -1, 10) 27 | fmt.Println("Sum:", sum) 28 | s := []int{1, 2, 3} 29 | sum = oneByOne("Adding numbers...", s...) 30 | fmt.Println(s) 31 | } 32 | -------------------------------------------------------------------------------- /ch12/atomWWW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "runtime" 7 | "sync/atomic" 8 | ) 9 | 10 | var count int32 11 | 12 | func handleAll(w http.ResponseWriter, r *http.Request) { 13 | atomic.AddInt32(&count, 1) 14 | } 15 | 16 | func getCounter(w http.ResponseWriter, r *http.Request) { 17 | temp := atomic.LoadInt32(&count) 18 | fmt.Println("Count:", temp) 19 | fmt.Fprintf(w, "

%d

", count) 20 | } 21 | 22 | func main() { 23 | runtime.GOMAXPROCS(runtime.NumCPU() - 1) 24 | http.HandleFunc("/getCounter", getCounter) 25 | http.HandleFunc("/", handleAll) 26 | http.ListenAndServe(":8080", nil) 27 | } 28 | -------------------------------------------------------------------------------- /ch14/neural.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | 8 | "github.com/goml/gobrain" 9 | ) 10 | 11 | func main() { 12 | seed := time.Now().Unix() 13 | rand.Seed(seed) 14 | 15 | patterns := [][][]float64{ 16 | {{0, 0, 0, 0}, {0}}, 17 | {{0, 1, 0, 1}, {1}}, 18 | {{1, 0, 1, 0}, {1}}, 19 | {{1, 1, 1, 1}, {1}}, 20 | } 21 | 22 | ff := &gobrain.FeedForward{} 23 | ff.Init(4, 2, 1) 24 | ff.Train(patterns, 1000, 0.6, 0.4, false) 25 | 26 | in := []float64{1, 1, 0, 1} 27 | out := ff.Update(in) 28 | fmt.Println(out) 29 | 30 | in = []float64{0, 0, 0, 0} 31 | out = ff.Update(in) 32 | fmt.Println(out) 33 | } 34 | -------------------------------------------------------------------------------- /ch11/quick_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | "testing/quick" 6 | ) 7 | 8 | var N = 1000000 9 | 10 | func TestWithSystem(t *testing.T) { 11 | condition := func(a, b uint16) bool { 12 | return Add(a, b) == (b + a) 13 | } 14 | 15 | err := quick.Check(condition, &quick.Config{MaxCount: N}) 16 | if err != nil { 17 | t.Errorf("Error: %v", err) 18 | } 19 | } 20 | 21 | func TestWithItself(t *testing.T) { 22 | condition := func(a, b uint16) bool { 23 | return Add(a, b) == Add(b, a) 24 | } 25 | 26 | err := quick.Check(condition, &quick.Config{MaxCount: N}) 27 | if err != nil { 28 | t.Errorf("Error: %v", err) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ch08/handleTwo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handleSignal(signal os.Signal) { 12 | fmt.Println("handleSignal() Caught:", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs, os.Interrupt, syscall.SIGINFO) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | switch sig { 22 | case os.Interrupt: 23 | fmt.Println("Caught:", sig) 24 | case syscall.SIGINFO: 25 | handleSignal(sig) 26 | return 27 | } 28 | } 29 | }() 30 | 31 | for { 32 | fmt.Printf(".") 33 | time.Sleep(20 * time.Second) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch11/documentMe.go: -------------------------------------------------------------------------------- 1 | // This package is for showcasing the documentation capabilities of Go 2 | // It is a naive package! 3 | package documentMe 4 | 5 | // Pie is a global variable 6 | // This is a silly comment! 7 | const Pie = 3.1415912 8 | 9 | // The S1() function finds the length of a string 10 | // It iterates over the string using range 11 | func S1(s string) int { 12 | if s == "" { 13 | return 0 14 | } 15 | n := 0 16 | for range s { 17 | n++ 18 | } 19 | return n 20 | } 21 | 22 | // The F1() function returns the double value of its input integer 23 | // A better function name would have been Double()! 24 | func F1(n int) int { 25 | return 2 * n 26 | } 27 | -------------------------------------------------------------------------------- /ch10/sillySort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | 14 | if len(arguments) == 1 { 15 | fmt.Println(os.Args[0], "n1, n2, [n]") 16 | return 17 | } 18 | 19 | var wg sync.WaitGroup 20 | for _, arg := range arguments[1:] { 21 | n, err := strconv.Atoi(arg) 22 | if err != nil || n < 0 { 23 | fmt.Print(". ") 24 | continue 25 | } 26 | 27 | wg.Add(1) 28 | go func(n int) { 29 | defer wg.Done() 30 | time.Sleep(time.Duration(n) * time.Second) 31 | fmt.Print(n, " ") 32 | }(n) 33 | } 34 | 35 | wg.Wait() 36 | fmt.Println() 37 | } 38 | -------------------------------------------------------------------------------- /ch06/html.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doing Maths in Go! 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {{ range . }} 28 | 29 | 30 | 31 | 32 | 33 | {{ end }} 34 | 35 |
NumberDoubleSquare
{{ .Number }} {{ .Double }} {{ .Square }}
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ch06/textT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "text/template" 7 | ) 8 | 9 | type Entry struct { 10 | Number int 11 | Square int 12 | } 13 | 14 | func main() { 15 | arguments := os.Args 16 | if len(arguments) != 2 { 17 | fmt.Println("Need the template file!") 18 | return 19 | } 20 | 21 | tFile := arguments[1] 22 | DATA := [][]int{{-1, 1}, {-2, 4}, {-3, 9}, {-4, 16}} 23 | var Entries []Entry 24 | 25 | for _, i := range DATA { 26 | if len(i) == 2 { 27 | temp := Entry{Number: i[0], Square: i[1]} 28 | Entries = append(Entries, temp) 29 | } 30 | } 31 | 32 | t := template.Must(template.ParseGlob(tFile)) 33 | t.Execute(os.Stdout, Entries) 34 | } 35 | -------------------------------------------------------------------------------- /ch03/deleteSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | aSlice := []int{1, 2, 4, 5, 6, 7} 7 | fmt.Println(aSlice) 8 | 9 | // Delete element at index i 10 | i := 3 11 | if i > len(aSlice) { 12 | fmt.Println("Cannot delete element", i) 13 | return 14 | } 15 | aSlice = append(aSlice[:i], aSlice[i+1:]...) 16 | fmt.Println(aSlice) 17 | 18 | // Delete element at index i 19 | i = 0 20 | if i > len(aSlice) { 21 | fmt.Println("Cannot delete element", i) 22 | return 23 | } 24 | // Replace element at index i with last element 25 | copy(aSlice[i:], aSlice[i+1:]) 26 | // Remove last element 27 | aSlice = aSlice[:len(aSlice)-1] 28 | fmt.Println(aSlice) 29 | } 30 | -------------------------------------------------------------------------------- /ch08/bytes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | func main() { 11 | var buffer bytes.Buffer 12 | buffer.Write([]byte("This is")) 13 | fmt.Fprintf(&buffer, " a string!\n") 14 | buffer.WriteTo(os.Stdout) 15 | buffer.WriteTo(os.Stdout) 16 | 17 | buffer.Reset() 18 | buffer.Write([]byte("Mastering Go!")) 19 | r := bytes.NewReader([]byte(buffer.String())) 20 | fmt.Println(buffer.String()) 21 | for { 22 | b := make([]byte, 3) 23 | n, err := r.Read(b) 24 | if err == io.EOF { 25 | break 26 | } 27 | 28 | if err != nil { 29 | fmt.Println(err) 30 | continue 31 | } 32 | fmt.Printf("Read %s Bytes: %d\n", b, n) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch10/raceC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) != 2 { 13 | fmt.Println("Give me a natural number!") 14 | return 15 | } 16 | numGR, err := strconv.Atoi(os.Args[1]) 17 | if err != nil { 18 | fmt.Println(err) 19 | return 20 | } 21 | 22 | var waitGroup sync.WaitGroup 23 | var i int 24 | 25 | k := make(map[int]int) 26 | k[1] = 12 27 | 28 | for i = 0; i < numGR; i++ { 29 | waitGroup.Add(1) 30 | go func() { 31 | defer waitGroup.Done() 32 | k[i] = i 33 | }() 34 | } 35 | 36 | k[2] = 10 37 | waitGroup.Wait() 38 | fmt.Printf("k = %#v\n", k) 39 | } 40 | -------------------------------------------------------------------------------- /ch03/usingMaps.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | iMap := make(map[string]int) 10 | iMap["k1"] = 12 11 | iMap["k2"] = 13 12 | fmt.Println("iMap:", iMap) 13 | 14 | anotherMap := map[string]int{ 15 | "k1": 12, 16 | "k2": 13, 17 | } 18 | 19 | fmt.Println("anotherMap:", anotherMap) 20 | delete(anotherMap, "k1") 21 | delete(anotherMap, "k1") 22 | delete(anotherMap, "k1") 23 | fmt.Println("anotherMap:", anotherMap) 24 | 25 | _, ok := iMap["doesItExist"] 26 | if ok { 27 | fmt.Println("Exists!") 28 | } else { 29 | fmt.Println("Does NOT exist") 30 | } 31 | 32 | for key, value := range iMap { 33 | fmt.Println(key, value) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch08/str.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | r := strings.NewReader("test") 12 | fmt.Println("r length:", r.Len()) 13 | 14 | b := make([]byte, 1) 15 | for { 16 | n, err := r.Read(b) 17 | if err == io.EOF { 18 | break 19 | } 20 | 21 | if err != nil { 22 | fmt.Println(err) 23 | continue 24 | } 25 | fmt.Printf("Read %s Bytes: %d\n", b, n) 26 | } 27 | 28 | s := strings.NewReader("This is an error!\n") 29 | fmt.Println("r length:", s.Len()) 30 | n, err := s.WriteTo(os.Stderr) 31 | 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | fmt.Printf("Wrote %d bytes to os.Stderr\n", n) 37 | } 38 | 39 | -------------------------------------------------------------------------------- /ch02/moreUnsafe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | array := [...]int{0, 1, -2, 3, 4} 10 | pointer := &array[0] 11 | fmt.Print(*pointer, " ") 12 | memoryAddress := uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 13 | 14 | for i := 0; i < len(array)-1; i++ { 15 | pointer = (*int)(unsafe.Pointer(memoryAddress)) 16 | fmt.Print(*pointer, " ") 17 | memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 18 | } 19 | fmt.Println() 20 | pointer = (*int)(unsafe.Pointer(memoryAddress)) 21 | fmt.Print("One more: ", *pointer, " ") 22 | memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 23 | fmt.Println() 24 | } 25 | -------------------------------------------------------------------------------- /ch04/pointerStruct.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type myStructure struct { 8 | Name string 9 | Surname string 10 | Height int32 11 | } 12 | 13 | func createStruct(n, s string, h int32) *myStructure { 14 | if h > 300 { 15 | h = 0 16 | } 17 | return &myStructure{n, s, h} 18 | } 19 | 20 | func retStructure(n, s string, h int32) myStructure { 21 | if h > 300 { 22 | h = 0 23 | } 24 | return myStructure{n, s, h} 25 | } 26 | 27 | func main() { 28 | s1 := createStruct("Mihalis", "Tsoukalos", 123) 29 | s2 := retStructure("Mihalis", "Tsoukalos", 123) 30 | fmt.Println((*s1).Name) 31 | fmt.Println(s1.Name) 32 | fmt.Println(s2.Name) 33 | fmt.Println(s1) 34 | fmt.Println(s2) 35 | } 36 | -------------------------------------------------------------------------------- /ch08/viper/readJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/viper" 6 | ) 7 | 8 | func main() { 9 | viper.SetConfigType("json") 10 | viper.SetConfigFile("./myJSONConfig.json") 11 | fmt.Printf("Using config: %s\n", viper.ConfigFileUsed()) 12 | viper.ReadInConfig() 13 | 14 | if viper.IsSet("item1.key1") { 15 | fmt.Println("item1.key1:", viper.Get("item1.key1")) 16 | } else { 17 | fmt.Println("item1.key1 not set!") 18 | } 19 | 20 | if viper.IsSet("item2.key3") { 21 | fmt.Println("item2.key3:", viper.Get("item2.key3")) 22 | } else { 23 | fmt.Println("item2.key3 is not set!") 24 | } 25 | 26 | if !viper.IsSet("item3.key1") { 27 | fmt.Println("item3.key1 is not set!") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch13/HTTPS/httpsClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | func main() { 14 | if len(os.Args) != 2 { 15 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 16 | return 17 | } 18 | URL := os.Args[1] 19 | 20 | tr := &http.Transport{ 21 | TLSClientConfig: &tls.Config{}, 22 | } 23 | client := &http.Client{Transport: tr} 24 | response, err := client.Get(URL) 25 | if err != nil { 26 | fmt.Println(err) 27 | return 28 | } 29 | defer response.Body.Close() 30 | 31 | content, _ := ioutil.ReadAll(response.Body) 32 | s := strings.TrimSpace(string(content)) 33 | 34 | fmt.Println(s) 35 | } 36 | -------------------------------------------------------------------------------- /ch03/lenCap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func printSlice(x []int) { 8 | for _, number := range x { 9 | fmt.Print(number, " ") 10 | } 11 | fmt.Println() 12 | } 13 | 14 | func main() { 15 | aSlice := []int{-1, 0, 4} 16 | fmt.Printf("aSlice: ") 17 | printSlice(aSlice) 18 | 19 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 20 | aSlice = append(aSlice, -100) 21 | fmt.Printf("aSlice: ") 22 | printSlice(aSlice) 23 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 24 | 25 | aSlice = append(aSlice, -2) 26 | aSlice = append(aSlice, -3) 27 | aSlice = append(aSlice, -4) 28 | printSlice(aSlice) 29 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 30 | } 31 | -------------------------------------------------------------------------------- /ch08/handleAll.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handle(signal os.Signal) { 12 | fmt.Println("Received:", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | switch sig { 22 | case os.Interrupt: 23 | handle(sig) 24 | case syscall.SIGTERM: 25 | handle(sig) 26 | os.Exit(0) 27 | case syscall.SIGUSR2: 28 | fmt.Println("Handling syscall.SIGUSR2!") 29 | default: 30 | fmt.Println("Ignoring:", sig) 31 | } 32 | } 33 | }() 34 | 35 | for { 36 | fmt.Printf(".") 37 | time.Sleep(30 * time.Second) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch01/customLogLineNumber.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | var LOGFILE = "/tmp/mGo.log" 10 | 11 | func main() { 12 | f, err := os.OpenFile(LOGFILE, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 13 | 14 | if err != nil { 15 | fmt.Println(err) 16 | return 17 | } 18 | defer f.Close() 19 | 20 | // LstdFlags = Ldate | Ltime 21 | // initial values for the standard logger 22 | iLog := log.New(f, "customLogLineNumber ", log.LstdFlags) 23 | 24 | // Print the line number of when and where something has happened 25 | iLog.SetFlags(log.LstdFlags | log.Lshortfile) 26 | iLog.Println("Hello there!") 27 | iLog.Println("Another log entry!") 28 | } 29 | -------------------------------------------------------------------------------- /ch01/logFiles.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | programName := filepath.Base(os.Args[0]) 13 | sysLog, err := syslog.New(syslog.LOG_INFO|syslog.LOG_LOCAL7, programName) 14 | if err != nil { 15 | log.Fatal(err) 16 | } else { 17 | log.SetOutput(sysLog) 18 | } 19 | log.Println("LOG_INFO + LOG_LOCAL7: Logging in Go!") 20 | 21 | sysLog, err = syslog.New(syslog.LOG_MAIL, "Some program!") 22 | if err != nil { 23 | log.Fatal(err) 24 | } else { 25 | log.SetOutput(sysLog) 26 | } 27 | 28 | log.Println("LOG_MAIL: Logging in Go!") 29 | fmt.Println("Will you see this?") 30 | } 31 | -------------------------------------------------------------------------------- /ch03/loops.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | for i := 0; i < 100; i++ { 9 | if i%20 == 0 { 10 | continue 11 | } 12 | 13 | if i == 95 { 14 | break 15 | } 16 | 17 | fmt.Print(i, " ") 18 | } 19 | 20 | fmt.Println() 21 | i := 10 22 | for { 23 | if i < 0 { 24 | break 25 | } 26 | fmt.Print(i, " ") 27 | i-- 28 | } 29 | fmt.Println() 30 | 31 | i = 0 32 | anExpression := true 33 | for ok := true; ok; ok = anExpression { 34 | if i > 10 { 35 | anExpression = false 36 | } 37 | 38 | fmt.Print(i, " ") 39 | i++ 40 | } 41 | fmt.Println() 42 | 43 | anArray := [5]int{0, 1, -1, 2, -2} 44 | for i, value := range anArray { 45 | fmt.Println("index:", i, "value: ", value) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ch08/cat.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | func printFile(filename string) error { 11 | f, err := os.Open(filename) 12 | if err != nil { 13 | return err 14 | } 15 | defer f.Close() 16 | scanner := bufio.NewScanner(f) 17 | for scanner.Scan() { 18 | io.WriteString(os.Stdout, scanner.Text()) 19 | io.WriteString(os.Stdout, "\n") 20 | } 21 | return nil 22 | } 23 | 24 | func main() { 25 | filename := "" 26 | arguments := os.Args 27 | if len(arguments) == 1 { 28 | io.Copy(os.Stdout, os.Stdin) 29 | return 30 | } 31 | 32 | for i := 1; i < len(arguments); i++ { 33 | filename = arguments[i] 34 | err := printFile(filename) 35 | if err != nil { 36 | fmt.Println(err) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch14/tfVersion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | tf "github.com/tensorflow/tensorflow/tensorflow/go" 5 | "github.com/tensorflow/tensorflow/tensorflow/go/op" 6 | "fmt" 7 | ) 8 | 9 | func main() { 10 | s := op.NewScope() 11 | c := op.Const(s, "Using TensorFlow version: " + tf.Version()) 12 | graph, err := s.Finalize() 13 | 14 | if err != nil { 15 | fmt.Println(err) 16 | return 17 | } 18 | 19 | sess, err := tf.NewSession(graph, nil) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | output, err := sess.Run(nil, []tf.Output{c}, nil) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | 31 | fmt.Println(output[0].Value()) 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /ch07/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type square struct { 8 | X float64 9 | } 10 | 11 | type circle struct { 12 | R float64 13 | } 14 | 15 | type rectangle struct { 16 | X float64 17 | Y float64 18 | } 19 | 20 | func tellInterface(x interface{}) { 21 | switch v := x.(type) { 22 | case square: 23 | fmt.Println("This is a square!") 24 | case circle: 25 | fmt.Printf("%v is a circle!\n", v) 26 | case rectangle: 27 | fmt.Println("This is a rectangle!") 28 | default: 29 | fmt.Printf("Unknown type %T!\n", v) 30 | } 31 | } 32 | 33 | func main() { 34 | x := circle{R: 10} 35 | tellInterface(x) 36 | y := rectangle{X: 4, Y: 1} 37 | tellInterface(y) 38 | z := square{X: 4} 39 | tellInterface(z) 40 | tellInterface(10) 41 | } 42 | -------------------------------------------------------------------------------- /ch08/cobra/cli/main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 NAME HERE 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import "cli/cmd" 18 | 19 | func main() { 20 | cmd.Execute() 21 | } 22 | -------------------------------------------------------------------------------- /ch06/functions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func doubleSquare(x int) (int, int) { 10 | return x * 2, x * x 11 | } 12 | 13 | func main() { 14 | arguments := os.Args 15 | if len(arguments) != 2 { 16 | fmt.Println("The program needs 1 argument!") 17 | return 18 | } 19 | 20 | y, err := strconv.Atoi(arguments[1]) 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | 26 | square := func(s int) int { 27 | return s * s 28 | } 29 | fmt.Println("The square of", y, "is", square(y)) 30 | 31 | double := func(s int) int { 32 | return s + s 33 | } 34 | fmt.Println("The double of", y, "is", double(y)) 35 | 36 | fmt.Println(doubleSquare(y)) 37 | d, s := doubleSquare(y) 38 | fmt.Println(d, s) 39 | } 40 | -------------------------------------------------------------------------------- /ch08/cobra/aliases/main.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2019 NAME HERE 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import "aliases/cmd" 18 | 19 | func main() { 20 | cmd.Execute() 21 | } 22 | -------------------------------------------------------------------------------- /ch10/noRaceC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | ) 9 | 10 | var aMutex sync.Mutex 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) != 2 { 15 | fmt.Println("Give me a natural number!") 16 | return 17 | } 18 | numGR, err := strconv.Atoi(os.Args[1]) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | 24 | var waitGroup sync.WaitGroup 25 | var i int 26 | 27 | k := make(map[int]int) 28 | k[1] = 12 29 | 30 | for i = 0; i < numGR; i++ { 31 | waitGroup.Add(1) 32 | go func(j int) { 33 | defer waitGroup.Done() 34 | aMutex.Lock() 35 | k[j] = j 36 | aMutex.Unlock() 37 | }(i) 38 | } 39 | 40 | waitGroup.Wait() 41 | k[2] = 10 42 | fmt.Printf("k = %#v\n", k) 43 | } 44 | -------------------------------------------------------------------------------- /ch01/newError.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func returnError(a, b int) error { 9 | if a == b { 10 | err := errors.New("Error in returnError() function!") 11 | return err 12 | } else { 13 | return nil 14 | } 15 | } 16 | 17 | func main() { 18 | err := returnError(1, 2) 19 | if err == nil { 20 | fmt.Println("returnError() ended normally!") 21 | } else { 22 | fmt.Println(err) 23 | } 24 | 25 | err = returnError(10, 10) 26 | if err == nil { 27 | fmt.Println("returnError() ended normally!") 28 | } else { 29 | fmt.Println(err) 30 | } 31 | 32 | if err.Error() == "Error in returnError() function!" { 33 | fmt.Println("!!") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch06/goParser.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/ast" 6 | "go/parser" 7 | "go/token" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type visitor int 13 | 14 | func (v visitor) Visit(n ast.Node) ast.Visitor { 15 | if n == nil { 16 | return nil 17 | } 18 | 19 | fmt.Printf("%s%T\n", strings.Repeat("\t", int(v)), n) 20 | return v + 1 21 | } 22 | 23 | func main() { 24 | if len(os.Args) == 1 { 25 | fmt.Println("Not enough arguments!") 26 | return 27 | } 28 | 29 | for _, file := range os.Args[1:] { 30 | fmt.Println("Processing:", file) 31 | one := token.NewFileSet() 32 | var v visitor 33 | f, err := parser.ParseFile(one, file, nil, parser.AllErrors) 34 | if err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | ast.Walk(v, f) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ch13/TCPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide host:port.") 15 | return 16 | } 17 | 18 | CONNECT := arguments[1] 19 | c, err := net.Dial("tcp", CONNECT) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | for { 26 | reader := bufio.NewReader(os.Stdin) 27 | fmt.Print(">> ") 28 | text, _ := reader.ReadString('\n') 29 | fmt.Fprintf(c, text+"\n") 30 | 31 | message, _ := bufio.NewReader(c).ReadString('\n') 32 | fmt.Print("->: " + message) 33 | if strings.TrimSpace(string(text)) == "STOP" { 34 | fmt.Println("TCP client exiting...") 35 | return 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch10/atom.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "sync" 7 | "sync/atomic" 8 | ) 9 | 10 | type atomCounter struct { 11 | val int64 12 | } 13 | 14 | func (c *atomCounter) Value() int64 { 15 | return atomic.LoadInt64(&c.val) 16 | } 17 | 18 | func main() { 19 | minusX := flag.Int("x", 100, "Goroutines") 20 | minusY := flag.Int("y", 200, "Value") 21 | flag.Parse() 22 | X := *minusX 23 | Y := *minusY 24 | 25 | var waitGroup sync.WaitGroup 26 | counter := atomCounter{} 27 | for i := 0; i < X; i++ { 28 | waitGroup.Add(1) 29 | go func(no int) { 30 | defer waitGroup.Done() 31 | for i := 0; i < Y; i++ { 32 | // counter.val++ 33 | atomic.AddInt64(&counter.val, 1) 34 | } 35 | }(i) 36 | } 37 | 38 | waitGroup.Wait() 39 | fmt.Println(counter.Value()) 40 | } 41 | -------------------------------------------------------------------------------- /ch03/numbers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | c1 := 12 + 1i 9 | c2 := complex(5, 7) 10 | fmt.Printf("Type of c1: %T\n", c1) 11 | fmt.Printf("Type of c2: %T\n", c2) 12 | 13 | var c3 complex64 = complex64(c1 + c2) 14 | fmt.Println("c3:", c3) 15 | fmt.Printf("Type of c3: %T\n", c3) 16 | 17 | cZero := c3 - c3 18 | fmt.Println("cZero:", cZero) 19 | 20 | x := 12 21 | k := 5 22 | fmt.Println(x) 23 | fmt.Printf("Type of x: %T\n", x) 24 | 25 | div := x / k 26 | fmt.Println("div", div) 27 | 28 | var m, n float64 29 | m = 1.223 30 | fmt.Println("m, n:", m, n) 31 | 32 | y := 4 / 2.3 33 | fmt.Println("y:", y) 34 | 35 | divFloat := float64(x) / float64(k) 36 | fmt.Println("divFloat", divFloat) 37 | fmt.Printf("Type of divFloat: %T\n", divFloat) 38 | } 39 | -------------------------------------------------------------------------------- /ch05/generatePassword.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func main() { 16 | MIN := 0 17 | MAX := 94 18 | var LENGTH int64 = 8 19 | 20 | arguments := os.Args 21 | switch len(arguments) { 22 | case 2: 23 | LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64) 24 | default: 25 | fmt.Println("Using default values!") 26 | } 27 | 28 | SEED := time.Now().Unix() 29 | rand.Seed(SEED) 30 | 31 | startChar := "!" 32 | var i int64 = 1 33 | for { 34 | myRand := random(MIN, MAX) 35 | newChar := string(startChar[0] + byte(myRand)) 36 | fmt.Print(newChar) 37 | if i == LENGTH { 38 | break 39 | } 40 | i++ 41 | } 42 | fmt.Println() 43 | } 44 | -------------------------------------------------------------------------------- /ch08/ptraceRegs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | var r syscall.PtraceRegs 13 | cmd := exec.Command(os.Args[1], os.Args[2:]...) 14 | 15 | cmd.Stdout = os.Stdout 16 | cmd.Stderr = os.Stderr 17 | 18 | cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true} 19 | err := cmd.Start() 20 | if err != nil { 21 | fmt.Println("Start:", err) 22 | return 23 | } 24 | 25 | err = cmd.Wait() 26 | fmt.Printf("State: %v\n", err) 27 | wpid := cmd.Process.Pid 28 | 29 | err = syscall.PtraceGetRegs(wpid, &r) 30 | if err != nil { 31 | fmt.Println("PtraceGetRegs:", err) 32 | return 33 | } 34 | fmt.Printf("Registers: %#v\n", r) 35 | fmt.Printf("R15=%d, Gs=%d\n", r.R15, r.Gs) 36 | 37 | time.Sleep(2 * time.Second) 38 | } 39 | -------------------------------------------------------------------------------- /ch13/syscallNet.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "syscall" 7 | ) 8 | 9 | func main() { 10 | fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) 11 | if err != nil { 12 | fmt.Println("Error in syscall.Socket:", err) 13 | return 14 | } 15 | 16 | f := os.NewFile(uintptr(fd), "captureICMP") 17 | if f == nil { 18 | fmt.Println("Error in os.NewFile:", err) 19 | return 20 | } 21 | 22 | err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, 256) 23 | if err != nil { 24 | fmt.Println("Error in syscall.Socket:", err) 25 | return 26 | } 27 | 28 | for { 29 | buf := make([]byte, 1024) 30 | numRead, err := f.Read(buf) 31 | if err != nil { 32 | fmt.Println(err) 33 | } 34 | fmt.Printf("% X\n", buf[:numRead]) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch03/execTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | start := time.Now() 10 | time.Sleep(time.Second) 11 | duration := time.Since(start) 12 | fmt.Println("It took time.Sleep(1)", duration, "to finish.") 13 | 14 | start = time.Now() 15 | time.Sleep(2 * time.Second) 16 | duration = time.Since(start) 17 | fmt.Println("It took time.Sleep(2)", duration, "to finish.") 18 | 19 | start = time.Now() 20 | for i := 0; i < 200000000; i++ { 21 | _ = i 22 | } 23 | duration = time.Since(start) 24 | fmt.Println("It took the for loop", duration, "to finish.") 25 | 26 | sum := 0 27 | start = time.Now() 28 | for i := 0; i < 200000000; i++ { 29 | sum += i 30 | } 31 | duration = time.Since(start) 32 | fmt.Println("It took the for loop", duration, "to finish.") 33 | } 34 | -------------------------------------------------------------------------------- /ch06/goScanner.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/scanner" 6 | "go/token" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) == 1 { 13 | fmt.Println("Not enough arguments!") 14 | return 15 | } 16 | 17 | for _, file := range os.Args[1:] { 18 | fmt.Println("Processing:", file) 19 | f, err := ioutil.ReadFile(file) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | one := token.NewFileSet() 25 | files := one.AddFile(file, one.Base(), len(f)) 26 | 27 | var myScanner scanner.Scanner 28 | myScanner.Init(files, f, nil, scanner.ScanComments) 29 | 30 | for { 31 | pos, tok, lit := myScanner.Scan() 32 | if tok == token.EOF { 33 | break 34 | } 35 | fmt.Printf("%s\t%s\t%q\n", one.Position(pos), tok, lit) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch03/constants.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Digit int 8 | type Power2 int 9 | 10 | const PI = 3.1415926 11 | 12 | const ( 13 | C1 = "C1C1C1" 14 | C2 = "C2C2C2" 15 | C3 = "C3C3C3" 16 | ) 17 | 18 | func main() { 19 | 20 | const s1 = 123 21 | var v1 float32 = s1 * 12 22 | fmt.Println(v1) 23 | fmt.Println(PI) 24 | 25 | // const s2 float64 = 123 26 | // var v2 float32 = s2 * 12 27 | 28 | const ( 29 | Zero Digit = iota 30 | One 31 | Two 32 | Three 33 | Four 34 | ) 35 | 36 | fmt.Println(One) 37 | fmt.Println(Two) 38 | 39 | const ( 40 | p2_0 Power2 = 1 << iota 41 | _ 42 | p2_2 43 | _ 44 | p2_4 45 | _ 46 | p2_6 47 | ) 48 | 49 | fmt.Println("2^0:", p2_0) 50 | fmt.Println("2^2:", p2_2) 51 | fmt.Println("2^4:", p2_4) 52 | fmt.Println("2^6:", p2_6) 53 | } 54 | -------------------------------------------------------------------------------- /ch13/RPCclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/rpc" 6 | "os" 7 | "sharedRPC" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a host:port string!") 14 | return 15 | } 16 | 17 | CONNECT := arguments[1] 18 | c, err := rpc.Dial("tcp", CONNECT) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | 24 | args := sharedRPC.MyFloats{16, -0.5} 25 | var reply float64 26 | 27 | err = c.Call("MyInterface.Multiply", args, &reply) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | fmt.Printf("Reply (Multiply): %f\n", reply) 33 | 34 | err = c.Call("MyInterface.Power", args, &reply) 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | fmt.Printf("Reply (Power): %f\n", reply) 40 | } 41 | -------------------------------------------------------------------------------- /ch04/writeJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func saveToJSON(filename *os.File, key interface{}) { 21 | encodeJSON := json.NewEncoder(filename) 22 | err := encodeJSON.Encode(key) 23 | if err != nil { 24 | fmt.Println(err) 25 | return 26 | } 27 | } 28 | 29 | func main() { 30 | myRecord := Record{ 31 | Name: "Mihalis", 32 | Surname: "Tsoukalos", 33 | Tel: []Telephone{Telephone{Mobile: true, Number: "1234-567"}, 34 | Telephone{Mobile: true, Number: "1234-abcd"}, 35 | Telephone{Mobile: false, Number: "abcc-567"}, 36 | }, 37 | } 38 | 39 | saveToJSON(os.Stdout, myRecord) 40 | } 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Mastering Go Second Edition 5 | Mastering Go Second Edition, published by Packt 6 | 7 | 8 | The Amazon.com page of the book is [here](https://www.amazon.com/Mastering-production-applications-concurrency-structures/dp/1838559337/). 9 | You can also visit the web page of the book at [Packt](https://www.packtpub.com/programming/mastering-go-second-edition). 10 | 11 | There is a **3rd edition** of Mastering Go! You can find more about it [here](https://github.com/mactsouk/mastering-Go-3rd). 12 | ### Download a free PDF 13 | 14 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
15 |

https://packt.link/free-ebook/9781838559335

-------------------------------------------------------------------------------- /ch02/gColl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func printStats(mem runtime.MemStats) { 10 | runtime.ReadMemStats(&mem) 11 | fmt.Println("mem.Alloc:", mem.Alloc) 12 | fmt.Println("mem.TotalAlloc:", mem.TotalAlloc) 13 | fmt.Println("mem.HeapAlloc:", mem.HeapAlloc) 14 | fmt.Println("mem.NumGC:", mem.NumGC) 15 | fmt.Println("-----") 16 | } 17 | 18 | func main() { 19 | var mem runtime.MemStats 20 | printStats(mem) 21 | 22 | for i := 0; i < 10; i++ { 23 | s := make([]byte, 50000000) 24 | if s == nil { 25 | fmt.Println("Operation failed!") 26 | } 27 | } 28 | printStats(mem) 29 | 30 | for i := 0; i < 10; i++ { 31 | s := make([]byte, 100000000) 32 | if s == nil { 33 | fmt.Println("Operation failed!") 34 | } 35 | time.Sleep(5 * time.Second) 36 | } 37 | printStats(mem) 38 | } 39 | -------------------------------------------------------------------------------- /ch03/slices.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | aSlice := []int{1, 2, 3, 4, 5} 9 | fmt.Println(aSlice) 10 | integers := make([]int, 2) 11 | fmt.Println(integers) 12 | 13 | integers = nil 14 | fmt.Println(integers) 15 | 16 | anArray := [5]int{-1, -2, -3, -4, -5} 17 | refAnArray := anArray[:] 18 | fmt.Println(anArray) 19 | fmt.Println(refAnArray) 20 | anArray[4] = -100 21 | fmt.Println(refAnArray) 22 | 23 | s := make([]byte, 5) 24 | fmt.Println(s) 25 | twoD := make([][]int, 3) 26 | fmt.Println(twoD) 27 | fmt.Println() 28 | 29 | for i := 0; i < len(twoD); i++ { 30 | for j := 0; j < 2; j++ { 31 | twoD[i] = append(twoD[i], i*j) 32 | } 33 | } 34 | 35 | for _, x := range twoD { 36 | for i, y := range x { 37 | fmt.Println("i:", i, "value:", y) 38 | } 39 | fmt.Println() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch08/byLine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | ) 10 | 11 | func lineByLine(file string) error { 12 | var err error 13 | f, err := os.Open(file) 14 | if err != nil { 15 | return err 16 | } 17 | defer f.Close() 18 | 19 | r := bufio.NewReader(f) 20 | for { 21 | line, err := r.ReadString('\n') 22 | if err == io.EOF { 23 | break 24 | } else if err != nil { 25 | fmt.Printf("error reading file %s", err) 26 | break 27 | } 28 | fmt.Print(line) 29 | } 30 | return nil 31 | } 32 | 33 | func main() { 34 | flag.Parse() 35 | if len(flag.Args()) == 0 { 36 | fmt.Printf("usage: byLine [ ...]\n") 37 | return 38 | } 39 | 40 | for _, file := range flag.Args() { 41 | err := lineByLine(file) 42 | if err != nil { 43 | fmt.Println(err) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch11/benchmarkMe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func fibo1(n int) int { 8 | if n == 0 { 9 | return 0 10 | } else if n == 1 { 11 | return 1 12 | } else { 13 | return fibo1(n-1) + fibo1(n-2) 14 | } 15 | } 16 | 17 | func fibo2(n int) int { 18 | if n == 0 || n == 1 { 19 | return n 20 | } 21 | return fibo2(n-1) + fibo2(n-2) 22 | } 23 | 24 | func fibo3(n int) int { 25 | fn := make(map[int]int) 26 | for i := 0; i <= n; i++ { 27 | var f int 28 | if i == 0 { 29 | f = 0 30 | } else if i <= 2 { 31 | f = 1 32 | } else { 33 | f = fn[i-1] + fn[i-2] 34 | } 35 | fn[i] = f 36 | } 37 | return fn[n] 38 | } 39 | 40 | func main() { 41 | fmt.Println(fibo1(0)) 42 | fmt.Println(fibo2(0)) 43 | fmt.Println(fibo3(0)) 44 | 45 | fmt.Println(fibo1(40)) 46 | fmt.Println(fibo2(40)) 47 | fmt.Println(fibo3(40)) 48 | } 49 | -------------------------------------------------------------------------------- /ch03/sortSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type aStructure struct { 9 | person string 10 | height int 11 | weight int 12 | } 13 | 14 | func main() { 15 | mySlice := make([]aStructure, 0) 16 | mySlice = append(mySlice, aStructure{"Mihalis", 180, 90}) 17 | mySlice = append(mySlice, aStructure{"Bill", 134, 45}) 18 | mySlice = append(mySlice, aStructure{"Marietta", 155, 45}) 19 | mySlice = append(mySlice, aStructure{"Epifanios", 144, 50}) 20 | mySlice = append(mySlice, aStructure{"Athina", 134, 40}) 21 | 22 | fmt.Println("0:", mySlice) 23 | sort.Slice(mySlice, func(i, j int) bool { 24 | return mySlice[i].height < mySlice[j].height 25 | }) 26 | fmt.Println("<:", mySlice) 27 | sort.Slice(mySlice, func(i, j int) bool { 28 | return mySlice[i].height > mySlice[j].height 29 | }) 30 | fmt.Println(">:", mySlice) 31 | } 32 | -------------------------------------------------------------------------------- /ch04/mUJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type Record struct { 9 | Name string 10 | Surname string 11 | Tel []Telephone 12 | } 13 | 14 | type Telephone struct { 15 | Mobile bool 16 | Number string 17 | } 18 | 19 | func main() { 20 | myRecord := Record{ 21 | Name: "Mihalis", 22 | Surname: "Tsoukalos", 23 | Tel: []Telephone{Telephone{Mobile: true, Number: "1234-567"}, 24 | Telephone{Mobile: true, Number: "1234-abcd"}, 25 | Telephone{Mobile: false, Number: "abcc-567"}, 26 | }} 27 | 28 | rec, err := json.Marshal(&myRecord) 29 | if err != nil { 30 | fmt.Println(err) 31 | return 32 | } 33 | fmt.Println(string(rec)) 34 | 35 | var unRec Record 36 | err1 := json.Unmarshal(rec, &unRec) 37 | if err1 != nil { 38 | fmt.Println(err1) 39 | return 40 | } 41 | fmt.Println(unRec) 42 | } 43 | -------------------------------------------------------------------------------- /ch03/usingArrays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | anArray := [4]int{1, 2, 4, -4} 9 | twoD := [4][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}} 10 | threeD := [2][2][2]int{{{1, 0}, {-2, 4}}, {{5, -1}, {7, 0}}} 11 | 12 | fmt.Println("The length of", anArray, "is", len(anArray)) 13 | fmt.Println("The first element of", twoD, "is", twoD[0][0]) 14 | fmt.Println("The length of", threeD, "is", len(threeD)) 15 | 16 | for i := 0; i < len(threeD); i++ { 17 | v := threeD[i] 18 | for j := 0; j < len(v); j++ { 19 | m := v[j] 20 | for k := 0; k < len(m); k++ { 21 | fmt.Print(m[k], " ") 22 | } 23 | } 24 | fmt.Println() 25 | } 26 | 27 | for _, v := range threeD { 28 | for _, m := range v { 29 | for _, s := range m { 30 | fmt.Print(s, " ") 31 | } 32 | } 33 | fmt.Println() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch11/writingBU_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | var ERR error 10 | 11 | func benchmarkCreate(b *testing.B, buffer, filesize int) { 12 | var err error 13 | for i := 0; i < b.N; i++ { 14 | err = Create("/tmp/random", buffer, filesize) 15 | } 16 | ERR = err 17 | 18 | err = os.Remove("/tmp/random") 19 | if err != nil { 20 | fmt.Println(err) 21 | } 22 | } 23 | 24 | func Benchmark1Create(b *testing.B) { 25 | benchmarkCreate(b, 1, 1000000) 26 | } 27 | 28 | func Benchmark2Create(b *testing.B) { 29 | benchmarkCreate(b, 2, 1000000) 30 | } 31 | 32 | func Benchmark4Create(b *testing.B) { 33 | benchmarkCreate(b, 4, 1000000) 34 | } 35 | 36 | func Benchmark10Create(b *testing.B) { 37 | benchmarkCreate(b, 10, 1000000) 38 | } 39 | 40 | func Benchmark1000Create(b *testing.B) { 41 | benchmarkCreate(b, 1000, 1000000) 42 | } 43 | -------------------------------------------------------------------------------- /ch02/logDefer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | var LOGFILE = "/tmp/mGo.log" 10 | 11 | func one(aLog *log.Logger) { 12 | aLog.Println("-- FUNCTION one ------") 13 | defer aLog.Println("-- FUNCTION one ------") 14 | 15 | for i := 0; i < 10; i++ { 16 | aLog.Println(i) 17 | } 18 | } 19 | 20 | func two(aLog *log.Logger) { 21 | aLog.Println("---- FUNCTION two") 22 | defer aLog.Println("FUNCTION two ------") 23 | 24 | for i := 10; i > 0; i-- { 25 | aLog.Println(i) 26 | } 27 | } 28 | 29 | func main() { 30 | f, err := os.OpenFile(LOGFILE, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 31 | if err != nil { 32 | fmt.Println(err) 33 | return 34 | } 35 | defer f.Close() 36 | 37 | iLog := log.New(f, "logDefer ", log.LstdFlags) 38 | iLog.Println("Hello there!") 39 | iLog.Println("Another log entry!") 40 | 41 | one(iLog) 42 | two(iLog) 43 | } 44 | -------------------------------------------------------------------------------- /ch06/returnNames.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func namedMinMax(x, y int) (min, max int) { 10 | if x > y { 11 | min = y 12 | max = x 13 | } else { 14 | min = x 15 | max = y 16 | } 17 | return 18 | } 19 | 20 | func minMax(x, y int) (min, max int) { 21 | if x > y { 22 | min = y 23 | max = x 24 | } else { 25 | min = x 26 | max = y 27 | } 28 | return min, max 29 | } 30 | 31 | func main() { 32 | arguments := os.Args 33 | if len(arguments) < 3 { 34 | fmt.Println("The program needs at least 2 arguments!") 35 | return 36 | } 37 | 38 | a1, _ := strconv.Atoi(arguments[1]) 39 | a2, _ := strconv.Atoi(arguments[2]) 40 | 41 | fmt.Println(minMax(a1, a2)) 42 | min, max := minMax(a1, a2) 43 | fmt.Println(min, max) 44 | 45 | fmt.Println(namedMinMax(a1, a2)) 46 | min, max = namedMinMax(a1, a2) 47 | fmt.Println(min, max) 48 | } 49 | -------------------------------------------------------------------------------- /ch12/gRPC/gServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | p "github.com/mactsouk/protobuf" 6 | "golang.org/x/net/context" 7 | "google.golang.org/grpc" 8 | "net" 9 | ) 10 | 11 | type MessageServer struct { 12 | } 13 | 14 | var port = ":8080" 15 | 16 | func (MessageServer) SayIt(ctx context.Context, r *p.Request) (*p.Response, error) { 17 | fmt.Println("Request Text:", r.Text) 18 | fmt.Println("Request SubText:", r.Subtext) 19 | 20 | response := &p.Response{ 21 | Text: r.Text, 22 | Subtext: "Got it!", 23 | } 24 | 25 | return response, nil 26 | } 27 | 28 | func main() { 29 | server := grpc.NewServer() 30 | var messageServer MessageServer 31 | p.RegisterMessageServiceServer(server, messageServer) 32 | listen, err := net.Listen("tcp", port) 33 | if err != nil { 34 | fmt.Println(err) 35 | return 36 | } 37 | fmt.Println("Serving requests...") 38 | server.Serve(listen) 39 | } 40 | -------------------------------------------------------------------------------- /ch08/byCharacter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | ) 10 | 11 | func charByChar(file string) error { 12 | var err error 13 | f, err := os.Open(file) 14 | if err != nil { 15 | return err 16 | } 17 | defer f.Close() 18 | 19 | r := bufio.NewReader(f) 20 | for { 21 | line, err := r.ReadString('\n') 22 | if err == io.EOF { 23 | break 24 | } else if err != nil { 25 | fmt.Printf("error reading file %s", err) 26 | return err 27 | } 28 | 29 | for _, x := range line { 30 | fmt.Println(string(x)) 31 | } 32 | } 33 | return nil 34 | } 35 | 36 | func main() { 37 | flag.Parse() 38 | if len(flag.Args()) == 0 { 39 | fmt.Printf("usage: byChar [ ...]\n") 40 | return 41 | } 42 | 43 | for _, file := range flag.Args() { 44 | err := charByChar(file) 45 | if err != nil { 46 | fmt.Println(err) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch13/HTTPS/TLSserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "crypto/x509" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | var PORT = ":1443" 12 | 13 | type handler struct { 14 | } 15 | 16 | func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { 17 | w.Write([]byte("Hello world!\n")) 18 | } 19 | 20 | func main() { 21 | caCert, err := ioutil.ReadFile("client.crt") 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | caCertPool := x509.NewCertPool() 28 | caCertPool.AppendCertsFromPEM(caCert) 29 | cfg := &tls.Config{ 30 | ClientAuth: tls.RequireAndVerifyClientCert, 31 | ClientCAs: caCertPool, 32 | } 33 | 34 | srv := &http.Server{ 35 | Addr: PORT, 36 | Handler: &handler{}, 37 | TLSConfig: cfg, 38 | } 39 | fmt.Println("Listening to port number", PORT) 40 | fmt.Println(srv.ListenAndServeTLS("server.crt", "server.key")) 41 | } 42 | -------------------------------------------------------------------------------- /ch10/slowWWW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "net/http" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func myHandler(w http.ResponseWriter, r *http.Request) { 16 | delay := random(0, 15) 17 | time.Sleep(time.Duration(delay) * time.Second) 18 | 19 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 20 | fmt.Fprintf(w, "Delay: %d\n", delay) 21 | fmt.Printf("Served: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | seed := time.Now().Unix() 26 | rand.Seed(seed) 27 | 28 | PORT := ":8001" 29 | arguments := os.Args 30 | if len(arguments) == 1 { 31 | fmt.Println("Using default port number: ", PORT) 32 | } else { 33 | PORT = ":" + arguments[1] 34 | } 35 | 36 | http.HandleFunc("/", myHandler) 37 | err := http.ListenAndServe(PORT, nil) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ch11/graph.dot: -------------------------------------------------------------------------------- 1 | digraph G 2 | { 3 | graph [dpi = 300, bgcolor = "gray"]; 4 | rankdir = LR; 5 | node [shape=record, width=.2, height=.2, color="white" ]; 6 | 7 | node0 [label = " | | | | | | ", height = 3]; 8 | node[ width=2 ]; 9 | node1 [label = "{ r0 | 123 |

}", color="gray" ]; 10 | node2 [label = "{ r10 | 13 |

}" ]; 11 | node3 [label = "{ r11 | 23 |

}" ]; 12 | node4 [label = "{ r12 | 326 |

}" ]; 13 | node5 [label = "{ r13 | 1f3 |

}" ]; 14 | node6 [label = "{ r20 | 143 |

}" ]; 15 | node7 [label = "{ r40 | b23 |

}" ]; 16 | 17 | node0:p0 -> node1:e [dir=both color="red:blue"]; 18 | node0:p1 -> node2:e [dir=back arrowhead=diamond]; 19 | node2:p -> node3:e; 20 | node3:p -> node4:e [dir=both arrowtail=box color="red"]; 21 | node4:p -> node5:e [dir=forward]; 22 | node0:p2 -> node6:e [dir=none color="orange"]; 23 | node0:p4 -> node7:e; 24 | } 25 | -------------------------------------------------------------------------------- /ch03/copySlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | a6 := []int{-10, 1, 2, 3, 4, 5} 9 | a4 := []int{-1, -2, -3, -4} 10 | fmt.Println("a6:", a6) 11 | fmt.Println("a4:", a4) 12 | 13 | copy(a6, a4) 14 | fmt.Println("a6:", a6) 15 | fmt.Println("a4:", a4) 16 | fmt.Println() 17 | 18 | b6 := []int{-10, 1, 2, 3, 4, 5} 19 | b4 := []int{-1, -2, -3, -4} 20 | fmt.Println("b6:", b6) 21 | fmt.Println("b4:", b4) 22 | copy(b4, b6) 23 | fmt.Println("b6:", b6) 24 | fmt.Println("b4:", b4) 25 | 26 | fmt.Println() 27 | array4 := [4]int{4, -4, 4, -4} 28 | s6 := []int{1, 1, -1, -1, 5, -5} 29 | copy(s6, array4[0:]) 30 | fmt.Println("array4:", array4[0:]) 31 | fmt.Println("s6:", s6) 32 | 33 | fmt.Println() 34 | 35 | array5 := [5]int{5, -5, 5, -5, 5} 36 | s7 := []int{7, 7, -7, -7, 7, -7, 7} 37 | copy(array5[0:], s7) 38 | fmt.Println("array5:", array5) 39 | fmt.Println("s7:", s7) 40 | } 41 | -------------------------------------------------------------------------------- /ch12/anotherTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "strconv" 9 | "time" 10 | ) 11 | 12 | var timeout = time.Duration(time.Second) 13 | 14 | func main() { 15 | if len(os.Args) == 1 { 16 | fmt.Println("Please provide a URL") 17 | return 18 | } 19 | 20 | if len(os.Args) == 3 { 21 | temp, err := strconv.Atoi(os.Args[2]) 22 | if err != nil { 23 | fmt.Println("Using Default Timeout!") 24 | } else { 25 | timeout = time.Duration(time.Duration(temp) * time.Second) 26 | } 27 | } 28 | 29 | URL := os.Args[1] 30 | 31 | client := http.Client{ 32 | Timeout: timeout, 33 | } 34 | client.Get(URL) 35 | 36 | data, err := client.Get(URL) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } else { 41 | defer data.Body.Close() 42 | _, err := io.Copy(os.Stdout, data.Body) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch05/conList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | "strconv" 7 | ) 8 | 9 | func printList(l *list.List) { 10 | for t := l.Back(); t != nil; t = t.Prev() { 11 | fmt.Print(t.Value, " ") 12 | } 13 | fmt.Println() 14 | 15 | for t := l.Front(); t != nil; t = t.Next() { 16 | fmt.Print(t.Value, " ") 17 | } 18 | 19 | fmt.Println() 20 | } 21 | 22 | func main() { 23 | values := list.New() 24 | 25 | e1 := values.PushBack("One") 26 | e2 := values.PushBack("Two") 27 | values.PushFront("Three") 28 | values.InsertBefore("Four", e1) 29 | values.InsertAfter("Five", e2) 30 | values.Remove(e2) 31 | values.Remove(e2) 32 | values.InsertAfter("FiveFive", e2) 33 | values.PushBackList(values) 34 | 35 | printList(values) 36 | 37 | values.Init() 38 | fmt.Printf("After Init(): %v\n", values) 39 | 40 | for i := 0; i < 20; i++ { 41 | values.PushFront(strconv.Itoa(i)) 42 | } 43 | 44 | printList(values) 45 | } 46 | -------------------------------------------------------------------------------- /ch08/cobra/cli/cmd/cmdOne.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | // cmdOneCmd represents the cmdOne command 9 | var cmdOneCmd = &cobra.Command{ 10 | Use: "cmdOne", 11 | Short: "A brief description of your command", 12 | Long: `A longer description that spans multiple lines and likely contains examples 13 | and usage of using your command. For example: 14 | 15 | Cobra is a CLI library for Go that empowers applications. 16 | This application is a tool to generate the needed files 17 | to quickly create a Cobra application.`, 18 | Run: func(cmd *cobra.Command, args []string) { 19 | fmt.Println("cmdOne called!") 20 | number, _ := cmd.Flags().GetInt("number") 21 | fmt.Println("Going to use number", number) 22 | fmt.Printf("Square: %d\n", number*number) 23 | }, 24 | } 25 | 26 | func init() { 27 | rootCmd.AddCommand(cmdOneCmd) 28 | cmdOneCmd.Flags().Int("number", 0, "A help for number") 29 | } 30 | -------------------------------------------------------------------------------- /ch11/betterProfile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/pkg/profile" 6 | ) 7 | 8 | var VARIABLE int 9 | 10 | func N1(n int) bool { 11 | for i := 2; i < n; i++ { 12 | if (n % i) == 0 { 13 | return false 14 | } 15 | } 16 | return true 17 | } 18 | 19 | func Multiply(a, b int) int { 20 | if a == 1 { 21 | return b 22 | } 23 | if a == 0 || b == 0 { 24 | return 0 25 | } 26 | if a < 0 { 27 | return -Multiply(-a, b) 28 | } 29 | return b + Multiply(a-1, b) 30 | } 31 | 32 | func main() { 33 | defer profile.Start(profile.ProfilePath("/tmp")).Stop() 34 | 35 | total := 0 36 | for i := 2; i < 200000; i++ { 37 | n := N1(i) 38 | if n { 39 | total++ 40 | } 41 | } 42 | fmt.Println("Total: ", total) 43 | 44 | total = 0 45 | for i := 0; i < 5000; i++ { 46 | for j := 0; j < 400; j++ { 47 | k := Multiply(i, j) 48 | VARIABLE = k 49 | total++ 50 | } 51 | } 52 | fmt.Println("Total: ", total) 53 | } 54 | -------------------------------------------------------------------------------- /ch04/readJSON.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func loadFromJSON(filename string, key interface{}) error { 21 | in, err := os.Open(filename) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | decodeJSON := json.NewDecoder(in) 27 | err = decodeJSON.Decode(key) 28 | if err != nil { 29 | return err 30 | } 31 | in.Close() 32 | return nil 33 | } 34 | 35 | func main() { 36 | arguments := os.Args 37 | if len(arguments) == 1 { 38 | fmt.Println("Please provide a filename!") 39 | return 40 | } 41 | 42 | filename := arguments[1] 43 | 44 | var myRecord Record 45 | err := loadFromJSON(filename, &myRecord) 46 | if err == nil { 47 | fmt.Println(myRecord) 48 | } else { 49 | fmt.Println(err) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ch12/gRPC/gClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | p "github.com/mactsouk/protobuf" 6 | "golang.org/x/net/context" 7 | "google.golang.org/grpc" 8 | ) 9 | 10 | var port = ":8080" 11 | 12 | func AboutToSayIt(ctx context.Context, m p.MessageServiceClient, text string) (*p.Response, error) { 13 | request := &p.Request{ 14 | Text: text, 15 | Subtext: "New Message!", 16 | } 17 | 18 | r, err := m.SayIt(ctx, request) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | return r, nil 24 | } 25 | 26 | func main() { 27 | conn, err := grpc.Dial(port, grpc.WithInsecure()) 28 | if err != nil { 29 | fmt.Println("Dial:", err) 30 | return 31 | } 32 | 33 | client := p.NewMessageServiceClient(conn) 34 | r, err := AboutToSayIt(context.Background(), client, "My Message!") 35 | if err != nil { 36 | fmt.Println(err) 37 | } 38 | 39 | fmt.Println("Response Text:", r.Text) 40 | fmt.Println("Response SubText:", r.Subtext) 41 | } 42 | -------------------------------------------------------------------------------- /ch04/readXML.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | type Record struct { 10 | Name string 11 | Surname string 12 | Tel []Telephone 13 | } 14 | 15 | type Telephone struct { 16 | Mobile bool 17 | Number string 18 | } 19 | 20 | func loadFromXML(filename string, key interface{}) error { 21 | in, err := os.Open(filename) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | decodeXML := xml.NewDecoder(in) 27 | err = decodeXML.Decode(key) 28 | if err != nil { 29 | return err 30 | } 31 | in.Close() 32 | return nil 33 | } 34 | 35 | func main() { 36 | arguments := os.Args 37 | if len(arguments) == 1 { 38 | fmt.Println("Please provide a filename!") 39 | return 40 | } 41 | 42 | filename := arguments[1] 43 | 44 | var myRecord Record 45 | err := loadFromXML(filename, &myRecord) 46 | if err == nil { 47 | fmt.Println("XML:", myRecord) 48 | } else { 49 | fmt.Println(err) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ch13/TCPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) == 1 { 15 | fmt.Println("Please provide port number") 16 | return 17 | } 18 | 19 | PORT := ":" + arguments[1] 20 | l, err := net.Listen("tcp", PORT) 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | defer l.Close() 26 | 27 | c, err := l.Accept() 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | 33 | for { 34 | netData, err := bufio.NewReader(c).ReadString('\n') 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | if strings.TrimSpace(string(netData)) == "STOP" { 40 | fmt.Println("Exiting TCP server!") 41 | return 42 | } 43 | 44 | fmt.Print("-> ", string(netData)) 45 | t := time.Now() 46 | myTime := t.Format(time.RFC3339) + "\n" 47 | c.Write([]byte(myTime)) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch04/modXML.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | type Address struct { 11 | City, Country string 12 | } 13 | type Employee struct { 14 | XMLName xml.Name `xml:"employee"` 15 | Id int `xml:"id,attr"` 16 | FirstName string `xml:"name>first"` 17 | LastName string `xml:"name>last"` 18 | Initials string `xml:"name>initials"` 19 | Height float32 `xml:"height,omitempty"` 20 | Address 21 | Comment string `xml:",comment"` 22 | } 23 | 24 | r := &Employee{Id: 7, FirstName: "Mihalis", LastName: "Tsoukalos", Initials: "MIT"} 25 | r.Comment = "Technical Writer + DevOps" 26 | r.Address = Address{"SomeWhere 12", "12312, Greece"} 27 | 28 | output, err := xml.MarshalIndent(r, " ", " ") 29 | if err != nil { 30 | fmt.Println("Error:", err) 31 | } 32 | output = []byte(xml.Header + string(output)) 33 | os.Stdout.Write(output) 34 | os.Stdout.Write([]byte("\n")) 35 | } 36 | -------------------------------------------------------------------------------- /ch05/cryptoRand.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/base64" 6 | "fmt" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | // This function returns (secure) random bytes 12 | func generateBytes(n int64) ([]byte, error) { 13 | b := make([]byte, n) 14 | _, err := rand.Read(b) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return b, nil 20 | } 21 | 22 | func generatePass(s int64) (string, error) { 23 | b, err := generateBytes(s) 24 | return base64.URLEncoding.EncodeToString(b), err 25 | } 26 | 27 | func main() { 28 | var LENGTH int64 = 8 29 | arguments := os.Args 30 | switch len(arguments) { 31 | case 2: 32 | LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64) 33 | if LENGTH <= 0 { 34 | LENGTH = 8 35 | } 36 | default: 37 | fmt.Println("Using default values!") 38 | } 39 | 40 | myPass, err := generatePass(LENGTH) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | fmt.Println(myPass[0:LENGTH]) 46 | } 47 | -------------------------------------------------------------------------------- /ch07/useInterface.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "myInterface" 7 | ) 8 | 9 | type square struct { 10 | X float64 11 | } 12 | 13 | type circle struct { 14 | R float64 15 | } 16 | 17 | func (s square) Area() float64 { 18 | return s.X * s.X 19 | } 20 | 21 | func (s square) Perimeter() float64 { 22 | return 4 * s.X 23 | } 24 | 25 | func (s circle) Area() float64 { 26 | return s.R * s.R * math.Pi 27 | } 28 | 29 | func (s circle) Perimeter() float64 { 30 | return 2 * s.R * math.Pi 31 | } 32 | 33 | func Calculate(x myInterface.Shape) { 34 | _, ok := x.(circle) 35 | if ok { 36 | fmt.Println("Is a circle!") 37 | } 38 | 39 | v, ok := x.(square) 40 | if ok { 41 | fmt.Println("Is a square:", v) 42 | } 43 | 44 | fmt.Println(x.Area()) 45 | fmt.Println(x.Perimeter()) 46 | } 47 | 48 | func main() { 49 | x := square{X: 10} 50 | fmt.Println("Perimeter:", x.Perimeter()) 51 | Calculate(x) 52 | y := circle{R: 5} 53 | Calculate(y) 54 | } 55 | -------------------------------------------------------------------------------- /ch10/select.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func gen(min, max int, createNumber chan int, end chan bool) { 12 | for { 13 | select { 14 | case createNumber <- rand.Intn(max-min) + min: 15 | case <-end: 16 | close(end) 17 | return 18 | case <-time.After(4 * time.Second): 19 | fmt.Println("\ntime.After()!") 20 | } 21 | } 22 | } 23 | 24 | func main() { 25 | rand.Seed(time.Now().Unix()) 26 | createNumber := make(chan int) 27 | end := make(chan bool) 28 | 29 | if len(os.Args) != 2 { 30 | fmt.Println("Please give me an integer!") 31 | return 32 | } 33 | 34 | n, _ := strconv.Atoi(os.Args[1]) 35 | fmt.Printf("Going to create %d random numbers.\n", n) 36 | go gen(0, 2*n, createNumber, end) 37 | 38 | for i := 0; i < n; i++ { 39 | fmt.Printf("%d ", <-createNumber) 40 | } 41 | 42 | time.Sleep(5 * time.Second) 43 | fmt.Println("Exiting...") 44 | end <- true 45 | } 46 | -------------------------------------------------------------------------------- /ch12/insert.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 | {{if .Success}} 15 |

Element inserted!

16 | {{else}} 17 |

Please fill in the fields:

18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 | {{end}} 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ch12/update.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 | {{if .Success}} 15 |

Element updated!

16 | {{else}} 17 |

Please fill in the fields:

18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 | {{end}} 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ch08/readSize.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | func readSize(f *os.File, size int) []byte { 11 | buffer := make([]byte, size) 12 | 13 | n, err := f.Read(buffer) 14 | if err == io.EOF { 15 | return nil 16 | } 17 | 18 | if err != nil { 19 | fmt.Println(err) 20 | return nil 21 | } 22 | 23 | return buffer[0:n] 24 | } 25 | 26 | func main() { 27 | arguments := os.Args 28 | if len(arguments) != 3 { 29 | fmt.Println(" ") 30 | return 31 | } 32 | 33 | bufferSize, err := strconv.Atoi(os.Args[1]) 34 | if err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | 39 | file := os.Args[2] 40 | f, err := os.Open(file) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | defer f.Close() 46 | 47 | for { 48 | readData := readSize(f, bufferSize) 49 | if readData != nil { 50 | fmt.Print(string(readData)) 51 | } else { 52 | break 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ch04/strings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | const sLiteral = "\x99\x42\x32\x55\x50\x35\x23\x50\x29\x9c" 9 | fmt.Println(sLiteral) 10 | fmt.Printf("x: %x\n", sLiteral) 11 | 12 | fmt.Printf("sLiteral length: %d\n", len(sLiteral)) 13 | 14 | for i := 0; i < len(sLiteral); i++ { 15 | fmt.Printf("%x ", sLiteral[i]) 16 | } 17 | fmt.Println() 18 | 19 | fmt.Printf("q: %q\n", sLiteral) 20 | fmt.Printf("+q: %+q\n", sLiteral) 21 | fmt.Printf(" x: % x\n", sLiteral) 22 | 23 | fmt.Printf("s: As a string: %s\n", sLiteral) 24 | 25 | s2 := "€£³" 26 | for x, y := range s2 { 27 | fmt.Printf("%#U starts at byte position %d\n", y, x) 28 | } 29 | 30 | fmt.Printf("s2 length: %d\n", len(s2)) 31 | 32 | const s3 = "ab12AB" 33 | fmt.Println("s3:", s3) 34 | fmt.Printf("x: % x\n", s3) 35 | 36 | fmt.Printf("s3 length: %d\n", len(s3)) 37 | 38 | for i := 0; i < len(s3); i++ { 39 | fmt.Printf("%x ", s3[i]) 40 | } 41 | fmt.Println() 42 | } 43 | -------------------------------------------------------------------------------- /ch10/mutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | var ( 12 | m sync.Mutex 13 | v1 int 14 | ) 15 | 16 | func change(i int) { 17 | m.Lock() 18 | time.Sleep(time.Second) 19 | v1 = v1 + 1 20 | if v1%10 == 0 { 21 | v1 = v1 - 10*i 22 | } 23 | m.Unlock() 24 | } 25 | 26 | func read() int { 27 | m.Lock() 28 | a := v1 29 | m.Unlock() 30 | return a 31 | } 32 | 33 | func main() { 34 | if len(os.Args) != 2 { 35 | fmt.Println("Please give me an integer!") 36 | return 37 | } 38 | 39 | numGR, err := strconv.Atoi(os.Args[1]) 40 | if err != nil { 41 | fmt.Println(err) 42 | return 43 | } 44 | var waitGroup sync.WaitGroup 45 | 46 | fmt.Printf("%d ", read()) 47 | for i := 0; i < numGR; i++ { 48 | waitGroup.Add(1) 49 | go func(i int) { 50 | defer waitGroup.Done() 51 | change(i) 52 | fmt.Printf("-> %d", read()) 53 | }(i) 54 | } 55 | 56 | waitGroup.Wait() 57 | fmt.Printf("-> %d\n", read()) 58 | } 59 | -------------------------------------------------------------------------------- /ch13/HTTPS/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICfDCCAWQCCQD7EyAuBlImmTANBgkqhkiG9w0BAQsFADAAMB4XDTE5MDUxNjE5 3 | MTcxOVoXDTI5MDUxMzE5MTcxOVowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC 4 | AQoCggEBALTTYdxFmDBiB89fSvPoJc3veQ/XYQbqrEFDP7aCYXn3HxxBhAV0ZPbl 5 | oJkPsrS8dRPD1N0Sk0tgcd9GEN7jac01Xk5HCB9uwaw4+nWXdnVD4Hwvf8UjrRQO 6 | v64IJX3+zO7cERopN35OKHHHdzBO42DNk7+SlK8jbXNqNq2N9qxRtKshIcE7tFzg 7 | 0DTfniXSgxtXJbKp7qjQscHWaJonqoTl5fMZN9ch/T6lRm392Y5ItxcSRi+1Wu1G 8 | YgdBnFm7/PWzAJTIMkh4Szj6Lb0y2lHHFTUr7DIzTsG96Bgq2uUstnpJoWTPYKbb 9 | P16RXAhAwrZTvu2DGrDaIGXHWy3Ktq0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA 10 | WrG3XOrcDYd0Jn+HFr56aFx+eXOGpbtJpMazBVeo0Vp6em2ub3qfoiqr49UsG0VX 11 | g/iG3k+kX1V8Er9YhWxydbqGjJ9aeo6U9BNO5dBZGnmP+jLcI/vNzaS4wNy1JiGY 12 | evuJsRFdljsGUoYK4Bim3VZJ/TsRQO4PdaOAsQKgPAujcDXxOQe+iBihuwwkXtSE 13 | kiletVIKTV/JN6fQ7FbuKt/bQSTDtmNwF32x1tq8Pou+Hg59pyT4PX/0ZIZKOj+j 14 | Xk97uugpmNbhmcEnApMFK3SPmPoMOw1ikiPjpjTIYGafAIwuVIvkcqXc7V1Mhhau 15 | WOznodWVSrID9InpefpBbw== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /ch12/testWWW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func CheckStatusOK(w http.ResponseWriter, r *http.Request) { 10 | w.WriteHeader(http.StatusOK) 11 | fmt.Fprintf(w, `Fine!`) 12 | } 13 | 14 | func StatusNotFound(w http.ResponseWriter, r *http.Request) { 15 | w.WriteHeader(http.StatusNotFound) 16 | } 17 | 18 | func MyHandler(w http.ResponseWriter, r *http.Request) { 19 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 20 | fmt.Printf("Served: %s\n", r.Host) 21 | } 22 | 23 | func main() { 24 | PORT := ":8001" 25 | arguments := os.Args 26 | if len(arguments) == 1 { 27 | fmt.Println("Using default port number: ", PORT) 28 | } else { 29 | PORT = ":" + arguments[1] 30 | } 31 | 32 | http.HandleFunc("/CheckStatusOK", CheckStatusOK) 33 | http.HandleFunc("/StatusNotFound", StatusNotFound) 34 | http.HandleFunc("/", MyHandler) 35 | 36 | err := http.ListenAndServe(PORT, nil) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch10/chSquare.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | var times int 11 | 12 | func f1(cc chan chan int, f chan bool) { 13 | c := make(chan int) 14 | cc <- c 15 | defer close(c) 16 | 17 | sum := 0 18 | select { 19 | case x := <-c: 20 | for i := 0; i <= x; i++ { 21 | sum = sum + i 22 | } 23 | c <- sum 24 | case <-f: 25 | return 26 | } 27 | } 28 | 29 | func main() { 30 | arguments := os.Args 31 | if len(arguments) != 2 { 32 | fmt.Println("Need just one integer argument!") 33 | return 34 | } 35 | 36 | times, err := strconv.Atoi(arguments[1]) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } 41 | 42 | cc := make(chan chan int) 43 | 44 | for i := 1; i < times+1; i++ { 45 | f := make(chan bool) 46 | go f1(cc, f) 47 | ch := <-cc 48 | ch <- i 49 | for sum := range ch { 50 | fmt.Print("Sum(", i, ")=", sum) 51 | } 52 | fmt.Println() 53 | time.Sleep(time.Second) 54 | close(f) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch08/byWord.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "regexp" 10 | ) 11 | 12 | func wordByWord(file string) error { 13 | var err error 14 | f, err := os.Open(file) 15 | if err != nil { 16 | return err 17 | } 18 | defer f.Close() 19 | 20 | r := bufio.NewReader(f) 21 | for { 22 | line, err := r.ReadString('\n') 23 | if err == io.EOF { 24 | break 25 | } else if err != nil { 26 | fmt.Printf("error reading file %s", err) 27 | return err 28 | } 29 | 30 | r := regexp.MustCompile("[^\\s]+") 31 | words := r.FindAllString(line, -1) 32 | for i := 0; i < len(words); i++ { 33 | fmt.Println(words[i]) 34 | } 35 | } 36 | return nil 37 | } 38 | 39 | func main() { 40 | flag.Parse() 41 | if len(flag.Args()) == 0 { 42 | fmt.Printf("usage: byWord [ ...]\n") 43 | return 44 | } 45 | 46 | for _, file := range flag.Args() { 47 | err := wordByWord(file) 48 | if err != nil { 49 | fmt.Println(err) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ch05/conHeap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/heap" 5 | "fmt" 6 | ) 7 | 8 | type heapFloat32 []float32 9 | 10 | func (n *heapFloat32) Pop() interface{} { 11 | old := *n 12 | x := old[len(old)-1] 13 | new := old[0 : len(old)-1] 14 | *n = new 15 | return x 16 | } 17 | 18 | func (n *heapFloat32) Push(x interface{}) { 19 | *n = append(*n, x.(float32)) 20 | } 21 | 22 | func (n heapFloat32) Len() int { 23 | return len(n) 24 | } 25 | 26 | func (n heapFloat32) Less(a, b int) bool { 27 | return n[a] < n[b] 28 | } 29 | 30 | func (n heapFloat32) Swap(a, b int) { 31 | n[a], n[b] = n[b], n[a] 32 | } 33 | 34 | func main() { 35 | myHeap := &heapFloat32{1.2, 2.1, 3.1, -100.1} 36 | heap.Init(myHeap) 37 | size := len(*myHeap) 38 | fmt.Printf("Heap size: %d\n", size) 39 | fmt.Printf("%v\n", myHeap) 40 | myHeap.Push(float32(-100.2)) 41 | myHeap.Push(float32(0.2)) 42 | fmt.Printf("Heap size: %d\n", len(*myHeap)) 43 | fmt.Printf("%v\n", myHeap) 44 | heap.Init(myHeap) 45 | fmt.Printf("%v\n", myHeap) 46 | } 47 | -------------------------------------------------------------------------------- /ch12/www.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func myHandler(w http.ResponseWriter, r *http.Request) { 11 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 12 | fmt.Printf("Served: %s\n", r.Host) 13 | } 14 | 15 | func timeHandler(w http.ResponseWriter, r *http.Request) { 16 | t := time.Now().Format(time.RFC1123) 17 | Body := "The current time is:" 18 | fmt.Fprintf(w, "

%s

", Body) 19 | fmt.Fprintf(w, "

%s

\n", t) 20 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 21 | fmt.Printf("Served time for: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | PORT := ":8001" 26 | arguments := os.Args 27 | if len(arguments) != 1 { 28 | PORT = ":" + arguments[1] 29 | } 30 | fmt.Println("Using port number: ", PORT) 31 | 32 | http.HandleFunc("/time", timeHandler) 33 | http.HandleFunc("/", myHandler) 34 | 35 | err := http.ListenAndServe(PORT, nil) 36 | if err != nil { 37 | fmt.Println(err) 38 | return 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ch11/testMe_test.go: -------------------------------------------------------------------------------- 1 | package testMe 2 | 3 | import "testing" 4 | 5 | func TestS1(t *testing.T) { 6 | if s1("123456789") != 9 { 7 | t.Error(`s1("123456789") != 9`) 8 | } 9 | 10 | if s1("") != 0 { 11 | t.Error(`s1("") != 0`) 12 | } 13 | } 14 | 15 | func TestS2(t *testing.T) { 16 | if s2("123456789") != 9 { 17 | t.Error(`s2("123456789") != 9`) 18 | } 19 | 20 | if s2("") != 0 { 21 | t.Error(`s2("") != 0`) 22 | } 23 | } 24 | 25 | func TestF1(t *testing.T) { 26 | if f1(0) != 0 { 27 | t.Error(`f1(0) != 0`) 28 | } 29 | 30 | if f1(1) != 1 { 31 | t.Error(`f1(1) != 1`) 32 | } 33 | 34 | if f1(2) != 1 { 35 | t.Error(`f1(2) != 1`) 36 | } 37 | 38 | if f1(10) != 55 { 39 | t.Error(`f1(10) != 55`) 40 | } 41 | } 42 | 43 | func TestF2(t *testing.T) { 44 | if f2(0) != 0 { 45 | t.Error(`f2(0) != 0`) 46 | } 47 | 48 | if f2(1) != 1 { 49 | t.Error(`f2(1) != 1`) 50 | } 51 | 52 | if f2(2) != 1 { 53 | t.Error(`f2(2) != 1`) 54 | } 55 | 56 | if f2(10) != 55 { 57 | t.Error(`f2(10) != 55`) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ch12/DNS.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func lookIP(address string) ([]string, error) { 10 | hosts, err := net.LookupAddr(address) 11 | if err != nil { 12 | return nil, err 13 | } 14 | return hosts, nil 15 | } 16 | 17 | func lookHostname(hostname string) ([]string, error) { 18 | IPs, err := net.LookupHost(hostname) 19 | if err != nil { 20 | return nil, err 21 | } 22 | return IPs, nil 23 | } 24 | 25 | func main() { 26 | arguments := os.Args 27 | if len(arguments) == 1 { 28 | fmt.Println("Please provide an argument!") 29 | return 30 | } 31 | 32 | input := arguments[1] 33 | IPaddress := net.ParseIP(input) 34 | 35 | if IPaddress == nil { 36 | IPs, err := lookHostname(input) 37 | if err == nil { 38 | for _, singleIP := range IPs { 39 | fmt.Println(singleIP) 40 | } 41 | } 42 | } else { 43 | hosts, err := lookIP(input) 44 | if err == nil { 45 | for _, hostname := range hosts { 46 | fmt.Println(hostname) 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ch13/otherTCPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide a server:port string!") 15 | return 16 | } 17 | 18 | CONNECT := arguments[1] 19 | tcpAddr, err := net.ResolveTCPAddr("tcp4", CONNECT) 20 | if err != nil { 21 | fmt.Println("ResolveTCPAddr:", err.Error()) 22 | return 23 | } 24 | 25 | conn, err := net.DialTCP("tcp4", nil, tcpAddr) 26 | if err != nil { 27 | fmt.Println("DialTCP:", err.Error()) 28 | return 29 | } 30 | 31 | for { 32 | reader := bufio.NewReader(os.Stdin) 33 | fmt.Print(">> ") 34 | text, _ := reader.ReadString('\n') 35 | fmt.Fprintf(conn, text+"\n") 36 | 37 | message, _ := bufio.NewReader(conn).ReadString('\n') 38 | fmt.Print("->: " + message) 39 | if strings.TrimSpace(string(text)) == "STOP" { 40 | fmt.Println("TCP client exiting...") 41 | conn.Close() 42 | return 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /ch06/varTimes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/scanner" 6 | "go/token" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | var KEYWORD = "var" 12 | var COUNT = 0 13 | 14 | func main() { 15 | if len(os.Args) == 1 { 16 | fmt.Println("Not enough arguments!") 17 | return 18 | } 19 | 20 | for _, file := range os.Args[1:] { 21 | fmt.Println("Processing:", file) 22 | f, err := ioutil.ReadFile(file) 23 | if err != nil { 24 | fmt.Println(err) 25 | return 26 | } 27 | one := token.NewFileSet() 28 | files := one.AddFile(file, one.Base(), len(f)) 29 | 30 | var myScanner scanner.Scanner 31 | myScanner.Init(files, f, nil, scanner.ScanComments) 32 | 33 | localCount := 0 34 | for { 35 | _, tok, lit := myScanner.Scan() 36 | if tok == token.EOF { 37 | break 38 | } 39 | 40 | if lit == KEYWORD { 41 | COUNT++ 42 | localCount++ 43 | } 44 | } 45 | fmt.Printf("Found _%s_ %d times\n", KEYWORD, localCount) 46 | } 47 | fmt.Printf("Found _%s_ %d times in total\n", KEYWORD, COUNT) 48 | } 49 | -------------------------------------------------------------------------------- /ch01/errors.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | func main() { 11 | if len(os.Args) == 1 { 12 | fmt.Println("Please give one or more floats.") 13 | os.Exit(1) 14 | } 15 | 16 | arguments := os.Args 17 | var err error = errors.New("An error") 18 | k := 1 19 | var n float64 20 | for err != nil { 21 | if k >= len(arguments) { 22 | fmt.Println("None of the arguments is a float!") 23 | return 24 | } 25 | n, err = strconv.ParseFloat(arguments[k], 64) 26 | k++ 27 | } 28 | 29 | min, max := n, n 30 | for i := 2; i < len(arguments); i++ { 31 | n, err := strconv.ParseFloat(arguments[i], 64) 32 | if err == nil { 33 | if n < min { 34 | min = n 35 | } 36 | if n > max { 37 | max = n 38 | } 39 | } 40 | } 41 | 42 | fmt.Println("Min:", min) 43 | fmt.Println("Max:", max) 44 | } 45 | -------------------------------------------------------------------------------- /ch05/hashTable.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const SIZE = 15 8 | type Node struct { 9 | Value int 10 | Next *Node 11 | } 12 | 13 | type HashTable struct { 14 | Table map[int]*Node 15 | Size int 16 | } 17 | 18 | func hashFunction(i, size int) int { 19 | return (i % size) 20 | } 21 | 22 | func insert(hash *HashTable, value int) int { 23 | index := hashFunction(value, hash.Size) 24 | element := Node{Value: value, Next: hash.Table[index]} 25 | hash.Table[index] = &element 26 | return index 27 | } 28 | 29 | func traverse(hash *HashTable) { 30 | for k := range hash.Table { 31 | if hash.Table[k] != nil { 32 | t := hash.Table[k] 33 | for t != nil { 34 | fmt.Printf("%d -> ", t.Value) 35 | t = t.Next 36 | } 37 | fmt.Println() 38 | } 39 | } 40 | } 41 | 42 | func main() { 43 | table := make(map[int]*Node, SIZE) 44 | hash := &HashTable{Table: table, Size: SIZE} 45 | fmt.Println("Number of spaces:", hash.Size) 46 | for i := 0; i < 120; i++ { 47 | insert(hash, i) 48 | } 49 | traverse(hash) 50 | } 51 | -------------------------------------------------------------------------------- /ch03/timeDate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | logs := []string{"127.0.0.1 - - [16/Nov/2017:10:49:46 +0200] 325504", 11 | "127.0.0.1 - - [16/Nov/2017:10:16:41 +0200] \"GET /CVEN HTTP/1.1\" 200 12531 \"-\" \"Mozilla/5.0 AppleWebKit/537.36", 12 | "127.0.0.1 200 9412 - - [12/Nov/2017:06:26:05 +0200] \"GET \"http://www.mtsoukalos.eu/taxonomy/term/47\" 1507", 13 | "[12/Nov/2017:16:27:21 +0300]", 14 | "[12/Nov/2017:20:88:21 +0200]", 15 | "[12/Nov/2017:20:21 +0200]", 16 | } 17 | 18 | for _, logEntry := range logs { 19 | r := regexp.MustCompile(`.*\[(\d\d\/\w+/\d\d\d\d:\d\d:\d\d:\d\d.*)\].*`) 20 | if r.MatchString(logEntry) { 21 | match := r.FindStringSubmatch(logEntry) 22 | dt, err := time.Parse("02/Jan/2006:15:04:05 -0700", match[1]) 23 | if err == nil { 24 | newFormat := dt.Format(time.RFC850) 25 | fmt.Println(newFormat) 26 | } else { 27 | fmt.Println("Not a valid date time format!") 28 | } 29 | } else { 30 | fmt.Println("Not a match!") 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ch14/readKafka.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "github.com/segmentio/kafka-go" 8 | "os" 9 | ) 10 | 11 | type Record struct { 12 | Name string `json:"name"` 13 | Random int `json:"random"` 14 | } 15 | 16 | func main() { 17 | if len(os.Args) < 2 { 18 | fmt.Println("Need a Kafka topic name.") 19 | return 20 | } 21 | 22 | partition := 0 23 | topic := os.Args[1] 24 | fmt.Println("Kafka topic:", topic) 25 | 26 | r := kafka.NewReader(kafka.ReaderConfig{ 27 | Brokers: []string{"localhost:9092"}, 28 | Topic: topic, 29 | Partition: partition, 30 | MinBytes: 10e3, 31 | MaxBytes: 10e6, 32 | }) 33 | r.SetOffset(0) 34 | 35 | for { 36 | m, err := r.ReadMessage(context.Background()) 37 | if err != nil { 38 | break 39 | } 40 | fmt.Printf("message at offset %d: %s = %s\n", m.Offset, string(m.Key), string(m.Value)) 41 | 42 | temp := Record{} 43 | err = json.Unmarshal(m.Value, &temp) 44 | if err != nil { 45 | fmt.Println(err) 46 | } 47 | fmt.Printf("%T\n", temp) 48 | } 49 | 50 | r.Close() 51 | } 52 | -------------------------------------------------------------------------------- /ch07/reflection.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "reflect" 7 | ) 8 | 9 | type a struct { 10 | X int 11 | Y float64 12 | Z string 13 | } 14 | 15 | type b struct { 16 | F int 17 | G int 18 | H string 19 | I float64 20 | } 21 | 22 | func main() { 23 | x := 100 24 | xRefl := reflect.ValueOf(&x).Elem() 25 | xType := xRefl.Type() 26 | fmt.Printf("The type of x is %s.\n", xType) 27 | // fmt.Printf("The type of x is %s.\n", reflect.TypeOf(x)) 28 | 29 | A := a{100, 200.12, "Struct a"} 30 | B := b{1, 2, "Struct b", -1.2} 31 | var r reflect.Value 32 | 33 | arguments := os.Args 34 | if len(arguments) == 1 { 35 | r = reflect.ValueOf(&A).Elem() 36 | } else { 37 | r = reflect.ValueOf(&B).Elem() 38 | } 39 | 40 | iType := r.Type() 41 | fmt.Printf("i Type: %s\n", iType) 42 | fmt.Printf("The %d fields of %s are:\n", r.NumField(), iType) 43 | 44 | for i := 0; i < r.NumField(); i++ { 45 | fmt.Printf("Field name: %s ", iType.Field(i).Name) 46 | fmt.Printf("with type: %s ", r.Field(i).Type()) 47 | fmt.Printf("and value %v\n", r.Field(i).Interface()) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch12/testWWW_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func TestCheckStatusOK(t *testing.T) { 11 | req, err := http.NewRequest("GET", "/CheckStatusOK", nil) 12 | if err != nil { 13 | fmt.Println(err) 14 | return 15 | } 16 | 17 | rr := httptest.NewRecorder() 18 | handler := http.HandlerFunc(CheckStatusOK) 19 | handler.ServeHTTP(rr, req) 20 | 21 | status := rr.Code 22 | if status != http.StatusOK { 23 | t.Errorf("handler returned %v", status) 24 | } 25 | 26 | expect := `Fine!` 27 | if rr.Body.String() != expect { 28 | t.Errorf("handler returned %v", rr.Body.String()) 29 | } 30 | } 31 | 32 | func TestStatusNotFound(t *testing.T) { 33 | req, err := http.NewRequest("GET", "/StatusNotFound", nil) 34 | if err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | 39 | rr := httptest.NewRecorder() 40 | handler := http.HandlerFunc(StatusNotFound) 41 | handler.ServeHTTP(rr, req) 42 | 43 | status := rr.Code 44 | if status != http.StatusNotFound { 45 | t.Errorf("handler returned %v", status) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ch14/anomaly.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "math/rand" 7 | "strconv" 8 | "time" 9 | 10 | "github.com/lytics/anomalyzer" 11 | ) 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func main() { 18 | flag.Parse() 19 | if len(flag.Args()) == 0 { 20 | fmt.Printf("usage: anomaly MAX\n") 21 | return 22 | } 23 | 24 | MAX, err := strconv.Atoi(flag.Args()[0]) 25 | if err != nil { 26 | fmt.Println(err) 27 | return 28 | } 29 | 30 | conf := &anomalyzer.AnomalyzerConf{ 31 | Sensitivity: 0.1, 32 | UpperBound: 5, 33 | LowerBound: anomalyzer.NA, 34 | ActiveSize: 1, 35 | NSeasons: 4, 36 | Methods: []string{"diff", "fence", "magnitude", "ks"}, 37 | } 38 | 39 | data := []float64{} 40 | SEED := time.Now().Unix() 41 | rand.Seed(SEED) 42 | 43 | for i := 0; i < MAX; i++ { 44 | data = append(data, float64(random(0, MAX))) 45 | } 46 | fmt.Println("data:", data) 47 | 48 | anom, _ := anomalyzer.NewAnomalyzer(conf, data) 49 | prob := anom.Push(8.0) 50 | fmt.Println("Anomalous Probability:", prob) 51 | } 52 | -------------------------------------------------------------------------------- /ch10/timeOut2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | func timeout(w *sync.WaitGroup, t time.Duration) bool { 12 | temp := make(chan int) 13 | go func() { 14 | time.Sleep(5 * time.Second) 15 | defer close(temp) 16 | w.Wait() 17 | }() 18 | 19 | select { 20 | case <-temp: 21 | return false 22 | case <-time.After(t): 23 | return true 24 | } 25 | } 26 | 27 | func main() { 28 | arguments := os.Args 29 | if len(arguments) != 2 { 30 | fmt.Println("Need a time duration!") 31 | return 32 | } 33 | 34 | var w sync.WaitGroup 35 | w.Add(1) 36 | 37 | t, err := strconv.Atoi(arguments[1]) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | 43 | duration := time.Duration(int32(t)) * time.Millisecond 44 | fmt.Printf("Timeout period is %s\n", duration) 45 | 46 | if timeout(&w, duration) { 47 | fmt.Println("Timed out!") 48 | } else { 49 | fmt.Println("OK!") 50 | } 51 | 52 | w.Done() 53 | if timeout(&w, duration) { 54 | fmt.Println("Timed out!") 55 | } else { 56 | fmt.Println("OK!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch14/classify.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "strconv" 7 | 8 | "github.com/sjwhitworth/golearn/base" 9 | "github.com/sjwhitworth/golearn/evaluation" 10 | "github.com/sjwhitworth/golearn/knn" 11 | ) 12 | 13 | func main() { 14 | flag.Parse() 15 | if len(flag.Args()) < 2 { 16 | fmt.Printf("usage: classify filename k\n") 17 | return 18 | } 19 | 20 | dataset := flag.Args()[0] 21 | rawData, err := base.ParseCSVToInstances(dataset, false) 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | k, err := strconv.Atoi(flag.Args()[1]) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | 33 | cls := knn.NewKnnClassifier("euclidean", "linear", k) 34 | train, test := base.InstancesTrainTestSplit(rawData, 0.50) 35 | cls.Fit(train) 36 | 37 | p, err := cls.Predict(test) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | 43 | confusionMat, err := evaluation.GetConfusionMatrix(test, p) 44 | if err != nil { 45 | fmt.Println(err) 46 | return 47 | } 48 | 49 | fmt.Println(evaluation.GetSummary(confusionMat)) 50 | } 51 | -------------------------------------------------------------------------------- /ch11/goGC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime" 7 | "runtime/trace" 8 | "time" 9 | ) 10 | 11 | func printStats(mem runtime.MemStats) { 12 | runtime.ReadMemStats(&mem) 13 | fmt.Println("mem.Alloc:", mem.Alloc) 14 | fmt.Println("mem.TotalAlloc:", mem.TotalAlloc) 15 | fmt.Println("mem.HeapAlloc:", mem.HeapAlloc) 16 | fmt.Println("mem.NumGC:", mem.NumGC) 17 | fmt.Println("-----") 18 | } 19 | 20 | func main() { 21 | f, err := os.Create("/tmp/traceFile.out") 22 | if err != nil { 23 | panic(err) 24 | } 25 | defer f.Close() 26 | 27 | err = trace.Start(f) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | defer trace.Stop() 33 | 34 | var mem runtime.MemStats 35 | printStats(mem) 36 | 37 | for i := 0; i < 3; i++ { 38 | s := make([]byte, 50000000) 39 | if s == nil { 40 | fmt.Println("Operation failed!") 41 | } 42 | } 43 | printStats(mem) 44 | 45 | for i := 0; i < 5; i++ { 46 | s := make([]byte, 100000000) 47 | if s == nil { 48 | fmt.Println("Operation failed!") 49 | } 50 | time.Sleep(time.Millisecond) 51 | } 52 | printStats(mem) 53 | } 54 | -------------------------------------------------------------------------------- /ch13/otherTCPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a port number!") 14 | return 15 | } 16 | 17 | SERVER := "localhost" + ":" + arguments[1] 18 | s, err := net.ResolveTCPAddr("tcp", SERVER) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | 24 | l, err := net.ListenTCP("tcp", s) 25 | if err != nil { 26 | fmt.Println(err) 27 | return 28 | } 29 | 30 | buffer := make([]byte, 1024) 31 | conn, err := l.Accept() 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | 37 | for { 38 | n, err := conn.Read(buffer) 39 | if err != nil { 40 | fmt.Println(err) 41 | return 42 | } 43 | 44 | if strings.TrimSpace(string(buffer[0:n])) == "STOP" { 45 | fmt.Println("Exiting TCP server!") 46 | conn.Close() 47 | return 48 | } 49 | 50 | fmt.Print("> ", string(buffer[0:n-1])) 51 | _, err = conn.Write(buffer) 52 | if err != nil { 53 | fmt.Println(err) 54 | return 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /ch02/wasm/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Go and WebAssembly 6 | 7 | 8 | 9 | 10 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ch14/cluster.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "github.com/mash/gokmeans" 7 | "strconv" 8 | ) 9 | 10 | var observations []gokmeans.Node = []gokmeans.Node{ 11 | gokmeans.Node{4}, 12 | gokmeans.Node{5}, 13 | gokmeans.Node{6}, 14 | gokmeans.Node{8}, 15 | gokmeans.Node{10}, 16 | gokmeans.Node{12}, 17 | gokmeans.Node{15}, 18 | gokmeans.Node{0}, 19 | gokmeans.Node{-1}, 20 | } 21 | 22 | func main() { 23 | flag.Parse() 24 | if len(flag.Args()) == 0 { 25 | fmt.Printf("usage: cluster k\n") 26 | return 27 | } 28 | 29 | k, err := strconv.Atoi(flag.Args()[0]) 30 | if err != nil { 31 | fmt.Println(err) 32 | return 33 | } 34 | 35 | if success, centroids := gokmeans.Train(observations, k, 50); success { 36 | fmt.Println("The centroids are the following:") 37 | for _, centroid := range centroids { 38 | fmt.Println(centroid) 39 | } 40 | 41 | fmt.Println("The clusters are the following:") 42 | for _, observation := range observations { 43 | index := gokmeans.Nearest(observation, centroids) 44 | fmt.Println(observation, "belongs in cluster", index+1, ".") 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ch10/monitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | var readValue = make(chan int) 13 | var writeValue = make(chan int) 14 | 15 | func set(newValue int) { 16 | writeValue <- newValue 17 | } 18 | 19 | func read() int { 20 | return <-readValue 21 | } 22 | 23 | func monitor() { 24 | var value int 25 | for { 26 | select { 27 | case newValue := <-writeValue: 28 | value = newValue 29 | fmt.Printf("%d ", value) 30 | case readValue <- value: 31 | } 32 | } 33 | } 34 | 35 | func main() { 36 | if len(os.Args) != 2 { 37 | fmt.Println("Please give an integer!") 38 | return 39 | } 40 | n, err := strconv.Atoi(os.Args[1]) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | 46 | fmt.Printf("Going to create %d random numbers.\n", n) 47 | rand.Seed(time.Now().Unix()) 48 | go monitor() 49 | var w sync.WaitGroup 50 | 51 | for r := 0; r < n; r++ { 52 | w.Add(1) 53 | go func() { 54 | defer w.Done() 55 | set(rand.Intn(10 * n)) 56 | }() 57 | } 58 | w.Wait() 59 | fmt.Printf("\nLast value: %d\n", read()) 60 | } 61 | -------------------------------------------------------------------------------- /ch08/funWithFlag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | type NamesFlag struct { 10 | Names []string 11 | } 12 | 13 | func (s *NamesFlag) GetNames() []string { 14 | return s.Names 15 | } 16 | 17 | func (s *NamesFlag) String() string { 18 | return fmt.Sprint(s.Names) 19 | } 20 | 21 | func (s *NamesFlag) Set(v string) error { 22 | if len(s.Names) > 0 { 23 | return fmt.Errorf("Cannot use names flag more than once!") 24 | } 25 | 26 | names := strings.Split(v, ",") 27 | for _, item := range names { 28 | s.Names = append(s.Names, item) 29 | } 30 | return nil 31 | } 32 | 33 | func main() { 34 | var manyNames NamesFlag 35 | minusK := flag.Int("k", 0, "An int") 36 | minusO := flag.String("o", "Mihalis", "The name") 37 | flag.Var(&manyNames, "names", "Comma-separated list") 38 | 39 | flag.Parse() 40 | fmt.Println("-k:", *minusK) 41 | fmt.Println("-o:", *minusO) 42 | 43 | for i, item := range manyNames.GetNames() { 44 | fmt.Println(i, item) 45 | } 46 | 47 | fmt.Println("Remaining command line arguments:") 48 | for index, val := range flag.Args() { 49 | fmt.Println(index, ":", val) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ch05/binTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | type Tree struct { 10 | Left *Tree 11 | Value int 12 | Right *Tree 13 | } 14 | 15 | func traverse(t *Tree) { 16 | if t == nil { 17 | return 18 | } 19 | traverse(t.Left) 20 | fmt.Print(t.Value, " ") 21 | traverse(t.Right) 22 | } 23 | 24 | func create(n int) *Tree { 25 | var t *Tree 26 | rand.Seed(time.Now().Unix()) 27 | for i := 0; i < 2*n; i++ { 28 | temp := rand.Intn(n * 2) 29 | t = insert(t, temp) 30 | } 31 | return t 32 | } 33 | 34 | func insert(t *Tree, v int) *Tree { 35 | if t == nil { 36 | return &Tree{nil, v, nil} 37 | } 38 | if v == t.Value { 39 | return t 40 | } 41 | if v < t.Value { 42 | t.Left = insert(t.Left, v) 43 | return t 44 | } 45 | t.Right = insert(t.Right, v) 46 | return t 47 | } 48 | 49 | func main() { 50 | tree := create(10) 51 | fmt.Println("The value of the root of the tree is", tree.Value) 52 | traverse(tree) 53 | fmt.Println() 54 | tree = insert(tree, -10) 55 | tree = insert(tree, -2) 56 | traverse(tree) 57 | fmt.Println() 58 | fmt.Println("The value of the root of the tree is", tree.Value) 59 | } 60 | -------------------------------------------------------------------------------- /ch13/UDPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide a host:port string") 15 | return 16 | } 17 | CONNECT := arguments[1] 18 | 19 | s, err := net.ResolveUDPAddr("udp4", CONNECT) 20 | c, err := net.DialUDP("udp4", nil, s) 21 | 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | fmt.Printf("The UDP server is %s\n", c.RemoteAddr().String()) 28 | defer c.Close() 29 | 30 | for { 31 | reader := bufio.NewReader(os.Stdin) 32 | fmt.Print(">> ") 33 | text, _ := reader.ReadString('\n') 34 | data := []byte(text + "\n") 35 | _, err = c.Write(data) 36 | if strings.TrimSpace(string(data)) == "STOP" { 37 | fmt.Println("Exiting UDP client!") 38 | return 39 | } 40 | 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | 46 | buffer := make([]byte, 1024) 47 | n, _, err := c.ReadFromUDP(buffer) 48 | if err != nil { 49 | fmt.Println(err) 50 | return 51 | } 52 | fmt.Printf("Reply: %s\n", string(buffer[0:n])) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ch13/RPCserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "net" 7 | "net/rpc" 8 | "os" 9 | "sharedRPC" 10 | ) 11 | 12 | type MyInterface struct{} 13 | var PORT = ":1234" 14 | 15 | func Power(x, y float64) float64 { 16 | return math.Pow(x, y) 17 | } 18 | 19 | func (t *MyInterface) Multiply(arguments *sharedRPC.MyFloats, reply *float64) error { 20 | *reply = arguments.A1 * arguments.A2 21 | return nil 22 | } 23 | 24 | func (t *MyInterface) Power(arguments *sharedRPC.MyFloats, reply *float64) error { 25 | *reply = Power(arguments.A1, arguments.A2) 26 | return nil 27 | } 28 | 29 | func main() { 30 | arguments := os.Args 31 | if len(arguments) != 1 { 32 | PORT = ":" + arguments[1] 33 | } 34 | 35 | myInterface := new(MyInterface) 36 | rpc.Register(myInterface) 37 | t, err := net.ResolveTCPAddr("tcp4", PORT) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | l, err := net.ListenTCP("tcp4", t) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | 48 | for { 49 | c, err := l.Accept() 50 | if err != nil { 51 | continue 52 | } 53 | fmt.Printf("%s\n", c.RemoteAddr()) 54 | rpc.ServeConn(c) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch04/selectColumn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) < 2 { 15 | fmt.Printf("usage: selectColumn column [ [... = column { 52 | fmt.Println((data[column-1])) 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch08/viper/readYAML.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | flag "github.com/spf13/pflag" 6 | "github.com/spf13/viper" 7 | "os" 8 | ) 9 | 10 | func main() { 11 | var configFile *string = flag.String("c", "myConfig", "Setting the configuration file") 12 | flag.Parse() 13 | 14 | _, err := os.Stat(*configFile) 15 | 16 | if err == nil { 17 | fmt.Println("Using User Specified Configuration file!") 18 | viper.SetConfigFile(*configFile) 19 | } else { 20 | viper.SetConfigName(*configFile) 21 | viper.AddConfigPath("/tmp") 22 | viper.AddConfigPath("$HOME") 23 | viper.AddConfigPath(".") 24 | } 25 | 26 | err = viper.ReadInConfig() 27 | if err != nil { 28 | fmt.Printf("%v\n", err) 29 | return 30 | } 31 | fmt.Printf("Using config: %s\n", viper.ConfigFileUsed()) 32 | 33 | if viper.IsSet("item1.k1") { 34 | fmt.Println("item1.val1:", viper.Get("item1.k1")) 35 | } else { 36 | fmt.Println("item1.k1 not set!") 37 | } 38 | 39 | if viper.IsSet("item1.k2") { 40 | fmt.Println("item1.val2:", viper.Get("item1.k2")) 41 | } else { 42 | fmt.Println("item1.k2 not set!") 43 | } 44 | 45 | if !viper.IsSet("item3.k1") { 46 | fmt.Println("item3.k1 is not set!") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch04/findIPv4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "net" 8 | "os" 9 | "path/filepath" 10 | "regexp" 11 | ) 12 | 13 | func findIP(input string) string { 14 | partIP := "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" 15 | grammar := partIP + "\\." + partIP + "\\." + partIP + "\\." + partIP 16 | matchMe := regexp.MustCompile(grammar) 17 | return matchMe.FindString(input) 18 | } 19 | 20 | func main() { 21 | arguments := os.Args 22 | if len(arguments) < 2 { 23 | fmt.Printf("usage: %s logFile\n", filepath.Base(arguments[0])) 24 | os.Exit(1) 25 | } 26 | 27 | for _, filename := range arguments[1:] { 28 | f, err := os.Open(filename) 29 | if err != nil { 30 | fmt.Printf("error opening file %s\n", err) 31 | os.Exit(-1) 32 | } 33 | defer f.Close() 34 | 35 | r := bufio.NewReader(f) 36 | for { 37 | line, err := r.ReadString('\n') 38 | if err == io.EOF { 39 | break 40 | } else if err != nil { 41 | fmt.Printf("error reading file %s", err) 42 | break 43 | } 44 | 45 | ip := findIP(line) 46 | trial := net.ParseIP(ip) 47 | if trial.To4() == nil { 48 | continue 49 | } 50 | fmt.Println(ip) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ch11/Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN apt-get update && apt-get install -y gnupg 4 | RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8 5 | RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list 6 | RUN apt-get update && apt-get install -y software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3 7 | RUN apt-get update && apt-get install -y git golang vim 8 | 9 | USER postgres 10 | RUN /etc/init.d/postgresql start &&\ 11 | psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\ 12 | createdb -O docker docker 13 | 14 | RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf 15 | RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf 16 | 17 | USER root 18 | RUN mkdir files 19 | COPY webServer.go files 20 | WORKDIR files 21 | RUN go get github.com/lib/pq 22 | RUN go build webServer.go 23 | RUN ls -l 24 | 25 | USER postgres 26 | CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"] 27 | -------------------------------------------------------------------------------- /ch12/serverTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func myHandler(w http.ResponseWriter, r *http.Request) { 11 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 12 | fmt.Printf("Served: %s\n", r.Host) 13 | } 14 | 15 | func timeHandler(w http.ResponseWriter, r *http.Request) { 16 | t := time.Now().Format(time.RFC1123) 17 | Body := "The current time is:" 18 | fmt.Fprintf(w, "

%s

", Body) 19 | fmt.Fprintf(w, "

%s

\n", t) 20 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 21 | fmt.Printf("Served time for: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | PORT := ":8001" 26 | arguments := os.Args 27 | if len(arguments) != 1 { 28 | PORT = ":" + arguments[1] 29 | } 30 | fmt.Println("Using port number: ", PORT) 31 | 32 | m := http.NewServeMux() 33 | srv := &http.Server{ 34 | Addr: PORT, 35 | Handler: m, 36 | ReadTimeout: 3 * time.Second, 37 | WriteTimeout: 3 * time.Second, 38 | } 39 | 40 | m.HandleFunc("/time", timeHandler) 41 | m.HandleFunc("/", myHandler) 42 | 43 | err := srv.ListenAndServe() 44 | if err != nil { 45 | fmt.Println(err) 46 | return 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch08/save.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | s := []byte("Data to write\n") 13 | 14 | f1, err := os.Create("f1.txt") 15 | if err != nil { 16 | fmt.Println("Cannot create file", err) 17 | return 18 | } 19 | defer f1.Close() 20 | fmt.Fprintf(f1, string(s)) 21 | 22 | f2, err := os.Create("f2.txt") 23 | if err != nil { 24 | fmt.Println("Cannot create file", err) 25 | return 26 | } 27 | defer f2.Close() 28 | n, err := f2.WriteString(string(s)) 29 | fmt.Printf("wrote %d bytes\n", n) 30 | 31 | f3, err := os.Create("f3.txt") 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | w := bufio.NewWriter(f3) 37 | n, err = w.WriteString(string(s)) 38 | fmt.Printf("wrote %d bytes\n", n) 39 | w.Flush() 40 | 41 | f4 := "f4.txt" 42 | err = ioutil.WriteFile(f4, s, 0644) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | 48 | f5, err := os.Create("f5.txt") 49 | if err != nil { 50 | fmt.Println(err) 51 | return 52 | } 53 | n, err = io.WriteString(f5, string(s)) 54 | if err != nil { 55 | fmt.Println(err) 56 | return 57 | } 58 | fmt.Printf("wrote %d bytes\n", n) 59 | } 60 | -------------------------------------------------------------------------------- /ch13/UDPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "net" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func main() { 18 | arguments := os.Args 19 | if len(arguments) == 1 { 20 | fmt.Println("Please provide a port number!") 21 | return 22 | } 23 | PORT := ":" + arguments[1] 24 | 25 | s, err := net.ResolveUDPAddr("udp4", PORT) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | 31 | connection, err := net.ListenUDP("udp4", s) 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | 37 | defer connection.Close() 38 | buffer := make([]byte, 1024) 39 | rand.Seed(time.Now().Unix()) 40 | 41 | for { 42 | n, addr, err := connection.ReadFromUDP(buffer) 43 | fmt.Print("-> ", string(buffer[0:n-1])) 44 | 45 | if strings.TrimSpace(string(buffer[0:n])) == "STOP" { 46 | fmt.Println("Exiting UDP server!") 47 | return 48 | } 49 | 50 | data := []byte(strconv.Itoa(random(1, 1001))) 51 | fmt.Printf("data: %s\n", string(data)) 52 | _, err = connection.WriteToUDP(data, addr) 53 | if err != nil { 54 | fmt.Println(err) 55 | return 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch12/clientTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "strconv" 11 | "time" 12 | ) 13 | 14 | var timeout = time.Duration(time.Second) 15 | 16 | func Timeout(network, host string) (net.Conn, error) { 17 | conn, err := net.DialTimeout(network, host, timeout) 18 | if err != nil { 19 | return nil, err 20 | } 21 | conn.SetDeadline(time.Now().Add(timeout)) 22 | return conn, nil 23 | } 24 | 25 | func main() { 26 | if len(os.Args) == 1 { 27 | fmt.Printf("Usage: %s URL TIMEOUT\n", filepath.Base(os.Args[0])) 28 | return 29 | } 30 | 31 | if len(os.Args) == 3 { 32 | temp, err := strconv.Atoi(os.Args[2]) 33 | if err != nil { 34 | fmt.Println("Using Default Timeout!") 35 | } else { 36 | timeout = time.Duration(time.Duration(temp) * time.Second) 37 | } 38 | } 39 | 40 | URL := os.Args[1] 41 | t := http.Transport{ 42 | Dial: Timeout, 43 | } 44 | 45 | client := http.Client{ 46 | Transport: &t, 47 | } 48 | 49 | data, err := client.Get(URL) 50 | if err != nil { 51 | fmt.Println(err) 52 | return 53 | } else { 54 | defer data.Body.Close() 55 | _, err := io.Copy(os.Stdout, data.Body) 56 | if err != nil { 57 | fmt.Println(err) 58 | return 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ch13/HTTPS/TLSclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "crypto/x509" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "os" 10 | "path/filepath" 11 | ) 12 | 13 | func main() { 14 | if len(os.Args) != 2 { 15 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 16 | return 17 | } 18 | URL := os.Args[1] 19 | 20 | caCert, err := ioutil.ReadFile("server.crt") 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | 26 | caCertPool := x509.NewCertPool() 27 | caCertPool.AppendCertsFromPEM(caCert) 28 | cert, err := tls.LoadX509KeyPair("client.crt", "client.key") 29 | 30 | if err != nil { 31 | fmt.Println(err) 32 | return 33 | } 34 | 35 | client := &http.Client{ 36 | Transport: &http.Transport{ 37 | TLSClientConfig: &tls.Config{ 38 | RootCAs: caCertPool, 39 | InsecureSkipVerify: true, 40 | Certificates: []tls.Certificate{cert}, 41 | }, 42 | }, 43 | } 44 | 45 | resp, err := client.Get(URL) 46 | if err != nil { 47 | fmt.Println(err) 48 | return 49 | } 50 | 51 | htmlData, err := ioutil.ReadAll(resp.Body) 52 | if err != nil { 53 | fmt.Println(err) 54 | return 55 | } 56 | 57 | defer resp.Body.Close() 58 | fmt.Printf("%v\n", resp.Status) 59 | fmt.Printf(string(htmlData)) 60 | } 61 | -------------------------------------------------------------------------------- /ch14/regression.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "flag" 6 | "fmt" 7 | "gonum.org/v1/gonum/stat" 8 | "os" 9 | "strconv" 10 | ) 11 | 12 | type xy struct { 13 | x []float64 14 | y []float64 15 | } 16 | 17 | func main() { 18 | flag.Parse() 19 | if len(flag.Args()) == 0 { 20 | fmt.Printf("usage: regression filename\n") 21 | return 22 | } 23 | 24 | filename := flag.Args()[0] 25 | file, err := os.Open(filename) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | defer file.Close() 31 | 32 | r := csv.NewReader(file) 33 | 34 | records, err := r.ReadAll() 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | size := len(records) 40 | 41 | data := xy{ 42 | x: make([]float64, size), 43 | y: make([]float64, size), 44 | } 45 | 46 | for i, v := range records { 47 | if len(v) != 2 { 48 | fmt.Println("Expected two elements") 49 | continue 50 | } 51 | 52 | if s, err := strconv.ParseFloat(v[0], 64); err == nil { 53 | data.y[i] = s 54 | } 55 | 56 | if s, err := strconv.ParseFloat(v[1], 64); err == nil { 57 | data.x[i] = s 58 | } 59 | } 60 | 61 | b, a := stat.LinearRegression(data.x, data.y, nil, false) 62 | fmt.Printf("%.4v x + %.4v\n", a, b) 63 | fmt.Printf("a = %.4v b = %.4v\n", a, b) 64 | } 65 | -------------------------------------------------------------------------------- /ch08/dockerAPI.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/docker/docker/api/types" 6 | "github.com/docker/docker/client" 7 | "golang.org/x/net/context" 8 | ) 9 | 10 | func listContainers() error { 11 | cli, err := client.NewEnvClient() 12 | if err != nil { 13 | return (err) 14 | } 15 | 16 | containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) 17 | if err != nil { 18 | return (err) 19 | } 20 | 21 | for _, container := range containers { 22 | fmt.Println("Images:", container.Image, "with ID:", container.ID) 23 | } 24 | return nil 25 | } 26 | 27 | func listImages() error { 28 | cli, err := client.NewEnvClient() 29 | if err != nil { 30 | return (err) 31 | } 32 | 33 | images, err := cli.ImageList(context.Background(), types.ImageListOptions{}) 34 | if err != nil { 35 | return (err) 36 | } 37 | 38 | for _, image := range images { 39 | fmt.Printf("Images %s with size %d\n", image.RepoTags, image.Size) 40 | } 41 | return nil 42 | } 43 | 44 | func main() { 45 | fmt.Println("The available images are:") 46 | err := listImages() 47 | if err != nil { 48 | fmt.Println(err) 49 | } 50 | 51 | fmt.Println("The running Containers are:") 52 | err = listContainers() 53 | if err != nil { 54 | fmt.Println(err) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch07/walkRef.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mitchellh/reflectwalk" 6 | "reflect" 7 | ) 8 | 9 | type Values struct { 10 | Extra map[string]string 11 | } 12 | 13 | type WalkMap struct { 14 | MapVal reflect.Value 15 | Keys map[string]bool 16 | Values map[string]bool 17 | } 18 | 19 | func (t *WalkMap) Map(m reflect.Value) error { 20 | t.MapVal = m 21 | return nil 22 | } 23 | 24 | func (t *WalkMap) MapElem(m, k, v reflect.Value) error { 25 | if t.Keys == nil { 26 | t.Keys = make(map[string]bool) 27 | t.Values = make(map[string]bool) 28 | } 29 | 30 | t.Keys[k.Interface().(string)] = true 31 | t.Values[v.Interface().(string)] = true 32 | return nil 33 | } 34 | 35 | func main() { 36 | w := new(WalkMap) 37 | 38 | type S struct { 39 | Map map[string]string 40 | } 41 | 42 | data := &S{ 43 | Map: map[string]string{ 44 | "V1": "v1v", 45 | "V2": "v2v", 46 | "V3": "v3v", 47 | "V4": "v4v", 48 | }, 49 | } 50 | 51 | err := reflectwalk.Walk(data, w) 52 | if err != nil { 53 | fmt.Println(err) 54 | return 55 | } 56 | 57 | r := w.MapVal 58 | fmt.Println("MapVal:", r) 59 | rType := r.Type() 60 | fmt.Printf("Type of r: %s\n", rType) 61 | 62 | for _, key := range r.MapKeys() { 63 | fmt.Println("key:", key, "value:", r.MapIndex(key)) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ch05/randomNumbers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func main() { 16 | MIN := 0 17 | MAX := 100 18 | TOTAL := 100 19 | SEED := time.Now().Unix() 20 | 21 | arguments := os.Args 22 | switch len(arguments) { 23 | case 2: 24 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 25 | MIN, _ = strconv.Atoi(arguments[1]) 26 | MAX = MIN + 100 27 | case 3: 28 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 29 | MIN, _ = strconv.Atoi(arguments[1]) 30 | MAX, _ = strconv.Atoi(arguments[2]) 31 | case 4: 32 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 33 | MIN, _ = strconv.Atoi(arguments[1]) 34 | MAX, _ = strconv.Atoi(arguments[2]) 35 | TOTAL, _ = strconv.Atoi(arguments[3]) 36 | case 5: 37 | MIN, _ = strconv.Atoi(arguments[1]) 38 | MAX, _ = strconv.Atoi(arguments[2]) 39 | TOTAL, _ = strconv.Atoi(arguments[3]) 40 | SEED, _ = strconv.ParseInt(arguments[4], 10, 64) 41 | default: 42 | fmt.Println("Using default values!") 43 | } 44 | 45 | rand.Seed(SEED) 46 | for i := 0; i < TOTAL; i++ { 47 | myrand := random(MIN, MAX) 48 | fmt.Print(myrand) 49 | fmt.Print(" ") 50 | } 51 | fmt.Println() 52 | } 53 | -------------------------------------------------------------------------------- /ch07/advRefl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "reflect" 7 | ) 8 | 9 | type t1 int 10 | type t2 int 11 | 12 | type a struct { 13 | X int 14 | Y float64 15 | Text string 16 | } 17 | 18 | func (a1 a) compareStruct(a2 a) bool { 19 | r1 := reflect.ValueOf(&a1).Elem() 20 | r2 := reflect.ValueOf(&a2).Elem() 21 | 22 | for i := 0; i < r1.NumField(); i++ { 23 | if r1.Field(i).Interface() != r2.Field(i).Interface() { 24 | return false 25 | } 26 | } 27 | return true 28 | } 29 | 30 | func printMethods(i interface{}) { 31 | r := reflect.ValueOf(i) 32 | t := r.Type() 33 | fmt.Printf("Type to examine: %s\n", t) 34 | 35 | for j := 0; j < r.NumMethod(); j++ { 36 | m := r.Method(j).Type() 37 | fmt.Println(t.Method(j).Name, "-->", m) 38 | } 39 | } 40 | 41 | func main() { 42 | x1 := t1(100) 43 | x2 := t2(100) 44 | fmt.Printf("The type of x1 is %s\n", reflect.TypeOf(x1)) 45 | fmt.Printf("The type of x2 is %s\n", reflect.TypeOf(x2)) 46 | 47 | var p struct{} 48 | r := reflect.New(reflect.ValueOf(&p).Type()).Elem() 49 | fmt.Printf("The type of r is %s\n", reflect.TypeOf(r)) 50 | 51 | a1 := a{1, 2.1, "A1"} 52 | a2 := a{1, -2, "A2"} 53 | 54 | if a1.compareStruct(a1) { 55 | fmt.Println("Equal!") 56 | } 57 | 58 | if !a1.compareStruct(a2) { 59 | fmt.Println("Not Equal!") 60 | } 61 | 62 | var f *os.File 63 | printMethods(f) 64 | } 65 | -------------------------------------------------------------------------------- /ch12/httpTrace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "net/http/httptrace" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Printf("Usage: URL\n") 14 | return 15 | } 16 | 17 | URL := os.Args[1] 18 | client := http.Client{} 19 | 20 | req, _ := http.NewRequest("GET", URL, nil) 21 | trace := &httptrace.ClientTrace{ 22 | GotFirstResponseByte: func() { 23 | fmt.Println("First response byte!") 24 | }, 25 | GotConn: func(connInfo httptrace.GotConnInfo) { 26 | fmt.Printf("Got Conn: %+v\n", connInfo) 27 | }, 28 | DNSDone: func(dnsInfo httptrace.DNSDoneInfo) { 29 | fmt.Printf("DNS Info: %+v\n", dnsInfo) 30 | }, 31 | ConnectStart: func(network, addr string) { 32 | fmt.Println("Dial start") 33 | }, 34 | ConnectDone: func(network, addr string, err error) { 35 | fmt.Println("Dial done") 36 | }, 37 | WroteHeaders: func() { 38 | fmt.Println("Wrote headers") 39 | }, 40 | } 41 | 42 | req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 43 | fmt.Println("Requesting data from server!") 44 | _, err := http.DefaultTransport.RoundTrip(req) 45 | if err != nil { 46 | fmt.Println(err) 47 | return 48 | } 49 | 50 | response, err := client.Do(req) 51 | if err != nil { 52 | fmt.Println(err) 53 | return 54 | } 55 | 56 | io.Copy(os.Stdout, response.Body) 57 | } 58 | -------------------------------------------------------------------------------- /ch13/fiboTCP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func f(n int) int { 14 | fn := make(map[int]int) 15 | for i := 0; i <= n; i++ { 16 | var f int 17 | if i <= 2 { 18 | f = 1 19 | } else { 20 | f = fn[i-1] + fn[i-2] 21 | } 22 | fn[i] = f 23 | } 24 | return fn[n] 25 | } 26 | 27 | func handleConnection(c net.Conn) { 28 | for { 29 | netData, err := bufio.NewReader(c).ReadString('\n') 30 | if err != nil { 31 | fmt.Println(err) 32 | os.Exit(100) 33 | } 34 | 35 | temp := strings.TrimSpace(string(netData)) 36 | if temp == "STOP" { 37 | break 38 | } 39 | 40 | fibo := "-1\n" 41 | n, err := strconv.Atoi(temp) 42 | if err == nil { 43 | fibo = strconv.Itoa(f(n)) + "\n" 44 | } 45 | c.Write([]byte(string(fibo))) 46 | } 47 | time.Sleep(5 * time.Second) 48 | c.Close() 49 | } 50 | 51 | func main() { 52 | arguments := os.Args 53 | if len(arguments) == 1 { 54 | fmt.Println("Please provide a port number!") 55 | return 56 | } 57 | 58 | PORT := ":" + arguments[1] 59 | l, err := net.Listen("tcp4", PORT) 60 | if err != nil { 61 | fmt.Println(err) 62 | return 63 | } 64 | defer l.Close() 65 | 66 | for { 67 | c, err := l.Accept() 68 | if err != nil { 69 | fmt.Println(err) 70 | return 71 | } 72 | go handleConnection(c) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ch09/pipeline.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | var CLOSEA = false 12 | 13 | var DATA = make(map[int]bool) 14 | 15 | func random(min, max int) int { 16 | return rand.Intn(max-min) + min 17 | } 18 | 19 | func first(min, max int, out chan<- int) { 20 | for { 21 | if CLOSEA { 22 | close(out) 23 | return 24 | } 25 | out <- random(min, max) 26 | } 27 | } 28 | 29 | func second(out chan<- int, in <-chan int) { 30 | for x := range in { 31 | fmt.Print(x, " ") 32 | _, ok := DATA[x] 33 | if ok { 34 | CLOSEA = true 35 | } else { 36 | DATA[x] = true 37 | out <- x 38 | } 39 | } 40 | fmt.Println() 41 | close(out) 42 | } 43 | 44 | func third(in <-chan int) { 45 | var sum int 46 | sum = 0 47 | for x2 := range in { 48 | sum = sum + x2 49 | } 50 | fmt.Printf("The sum of the random numbers is %d.\n", sum) 51 | } 52 | 53 | func main() { 54 | if len(os.Args) != 3 { 55 | fmt.Println("Need two integer parameters!") 56 | return 57 | } 58 | 59 | n1, _ := strconv.Atoi(os.Args[1]) 60 | n2, _ := strconv.Atoi(os.Args[2]) 61 | 62 | if n1 > n2 { 63 | fmt.Printf("%d should be smaller than %d.\n", n1, n2) 64 | return 65 | } 66 | 67 | rand.Seed(time.Now().UnixNano()) 68 | A := make(chan int) 69 | B := make(chan int) 70 | 71 | go first(n1, n2, A) 72 | go second(B, A) 73 | third(B) 74 | } 75 | -------------------------------------------------------------------------------- /ch05/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | var size = 0 13 | var stack = new(Node) 14 | 15 | func Push(v int) bool { 16 | if stack == nil { 17 | stack = &Node{v, nil} 18 | size = 1 19 | return true 20 | } 21 | 22 | temp := &Node{v, nil} 23 | temp.Next = stack 24 | stack = temp 25 | size++ 26 | return true 27 | } 28 | 29 | func Pop(t *Node) (int, bool) { 30 | if size == 0 { 31 | return 0, false 32 | } 33 | 34 | if size == 1 { 35 | size = 0 36 | stack = nil 37 | return t.Value, true 38 | } 39 | 40 | stack = stack.Next 41 | size-- 42 | return t.Value, true 43 | } 44 | 45 | func traverse(t *Node) { 46 | if size == 0 { 47 | fmt.Println("Empty Stack!") 48 | return 49 | } 50 | 51 | for t != nil { 52 | fmt.Printf("%d -> ", t.Value) 53 | t = t.Next 54 | } 55 | fmt.Println() 56 | } 57 | 58 | func main() { 59 | 60 | stack = nil 61 | v, b := Pop(stack) 62 | if b { 63 | fmt.Print(v, " ") 64 | } else { 65 | fmt.Println("Pop() failed!") 66 | } 67 | 68 | Push(100) 69 | traverse(stack) 70 | Push(200) 71 | traverse(stack) 72 | 73 | for i := 0; i < 10; i++ { 74 | Push(i) 75 | } 76 | 77 | for i := 0; i < 15; i++ { 78 | v, b := Pop(stack) 79 | if b { 80 | fmt.Print(v, " ") 81 | } else { 82 | break 83 | } 84 | } 85 | fmt.Println() 86 | traverse(stack) 87 | } 88 | -------------------------------------------------------------------------------- /ch12/wwwProfile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/pprof" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func myHandler(w http.ResponseWriter, r *http.Request) { 12 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 13 | fmt.Printf("Served: %s\n", r.Host) 14 | } 15 | 16 | func timeHandler(w http.ResponseWriter, r *http.Request) { 17 | t := time.Now().Format(time.RFC1123) 18 | Body := "The current time is:" 19 | fmt.Fprintf(w, "

%s

", Body) 20 | fmt.Fprintf(w, "

%s

\n", t) 21 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 22 | fmt.Printf("Served time for: %s\n", r.Host) 23 | } 24 | 25 | func main() { 26 | PORT := ":8001" 27 | arguments := os.Args 28 | if len(arguments) == 1 { 29 | fmt.Println("Using default port number: ", PORT) 30 | } else { 31 | PORT = ":" + arguments[1] 32 | fmt.Println("Using port number: ", PORT) 33 | } 34 | 35 | r := http.NewServeMux() 36 | r.HandleFunc("/time", timeHandler) 37 | r.HandleFunc("/", myHandler) 38 | 39 | r.HandleFunc("/debug/pprof/", pprof.Index) 40 | r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 41 | r.HandleFunc("/debug/pprof/profile", pprof.Profile) 42 | r.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 43 | r.HandleFunc("/debug/pprof/trace", pprof.Trace) 44 | 45 | err := http.ListenAndServe(PORT, r) 46 | if err != nil { 47 | fmt.Println(err) 48 | return 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ch05/hashTableLookup.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const SIZE = 15 8 | 9 | type Node struct { 10 | Value int 11 | Next *Node 12 | } 13 | 14 | type HashTable struct { 15 | Table map[int]*Node 16 | Size int 17 | } 18 | 19 | func hashFunction(i, size int) int { 20 | return (i % size) 21 | } 22 | 23 | func insert(hash *HashTable, value int) int { 24 | index := hashFunction(value, hash.Size) 25 | element := Node{Value: value, Next: hash.Table[index]} 26 | hash.Table[index] = &element 27 | return index 28 | } 29 | 30 | func traverse(hash *HashTable) { 31 | for k := range hash.Table { 32 | if hash.Table[k] != nil { 33 | t := hash.Table[k] 34 | for t != nil { 35 | fmt.Printf("%d -> ", t.Value) 36 | t = t.Next 37 | } 38 | fmt.Println() 39 | } 40 | } 41 | } 42 | 43 | func lookup(hash *HashTable, value int) bool { 44 | index := hashFunction(value, hash.Size) 45 | if hash.Table[index] != nil { 46 | t := hash.Table[index] 47 | for t != nil { 48 | if t.Value == value { 49 | return true 50 | } 51 | t = t.Next 52 | } 53 | } 54 | return false 55 | } 56 | 57 | func main() { 58 | table := make(map[int]*Node, SIZE) 59 | hash := &HashTable{Table: table, Size: SIZE} 60 | for i := 0; i < 120; i++ { 61 | insert(hash, i) 62 | } 63 | 64 | for i := 10; i < 125; i++ { 65 | if !lookup(hash, i) { 66 | fmt.Println(i, "is not in the hash table!") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ch08/CSVplot.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "github.com/Arafatk/glot" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Println("Need a data file!") 14 | return 15 | } 16 | 17 | file := os.Args[1] 18 | _, err := os.Stat(file) 19 | if err != nil { 20 | fmt.Println("Cannot stat", file) 21 | return 22 | } 23 | 24 | f, err := os.Open(file) 25 | if err != nil { 26 | fmt.Println("Cannot open", file) 27 | fmt.Println(err) 28 | return 29 | } 30 | defer f.Close() 31 | 32 | reader := csv.NewReader(f) 33 | reader.FieldsPerRecord = -1 34 | allRecords, err := reader.ReadAll() 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | 40 | xP := []float64{} 41 | yP := []float64{} 42 | for _, rec := range allRecords { 43 | x, _ := strconv.ParseFloat(rec[0], 64) 44 | y, _ := strconv.ParseFloat(rec[1], 64) 45 | xP = append(xP, x) 46 | yP = append(yP, y) 47 | } 48 | 49 | points := [][]float64{} 50 | points = append(points, xP) 51 | points = append(points, yP) 52 | fmt.Println(points) 53 | 54 | dimensions := 2 55 | persist := true 56 | debug := false 57 | plot, _ := glot.NewPlot(dimensions, persist, debug) 58 | 59 | plot.SetTitle("Using Glot with CSV data") 60 | plot.SetXLabel("X-Axis") 61 | plot.SetYLabel("Y-Axis") 62 | style := "circle" 63 | plot.AddPointGroup("Circle:", style, points) 64 | plot.SavePlot("output.png") 65 | } 66 | -------------------------------------------------------------------------------- /ch14/writeKafka.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "github.com/segmentio/kafka-go" 8 | "math/rand" 9 | "os" 10 | "strconv" 11 | "time" 12 | ) 13 | 14 | type Record struct { 15 | Name string `json:"name"` 16 | Random int `json:"random"` 17 | } 18 | 19 | func random(min, max int) int { 20 | return rand.Intn(max-min) + min 21 | } 22 | 23 | func main() { 24 | MIN := 0 25 | MAX := 0 26 | TOTAL := 0 27 | topic := "" 28 | if len(os.Args) > 4 { 29 | MIN, _ = strconv.Atoi(os.Args[1]) 30 | MAX, _ = strconv.Atoi(os.Args[2]) 31 | TOTAL, _ = strconv.Atoi(os.Args[3]) 32 | topic = os.Args[4] 33 | } else { 34 | fmt.Println("Usage:", os.Args[0], "MIX MAX TOTAL TOPIC") 35 | return 36 | } 37 | 38 | partition := 0 39 | conn, err := kafka.DialLeader(context.Background(), "tcp", "localhost:9092", topic, partition) 40 | if err != nil { 41 | fmt.Printf("%s\n", err) 42 | return 43 | } 44 | 45 | rand.Seed(time.Now().Unix()) 46 | 47 | for i := 0; i < TOTAL; i++ { 48 | myrand := random(MIN, MAX) 49 | temp := Record{strconv.Itoa(i), myrand} 50 | recordJSON, _ := json.Marshal(temp) 51 | 52 | conn.SetWriteDeadline(time.Now().Add(1 * time.Second)) 53 | conn.WriteMessages( 54 | kafka.Message{Value: []byte(recordJSON)}, 55 | ) 56 | 57 | if i%50 == 0 { 58 | fmt.Print(".") 59 | } 60 | time.Sleep(10 * time.Millisecond) 61 | } 62 | 63 | fmt.Println() 64 | conn.Close() 65 | } 66 | -------------------------------------------------------------------------------- /ch04/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | "strconv" 8 | ) 9 | 10 | func main() { 11 | 12 | arguments := os.Args 13 | if len(arguments) < 2 { 14 | fmt.Println("usage: switch number.") 15 | os.Exit(1) 16 | } 17 | 18 | number, err := strconv.Atoi(arguments[1]) 19 | if err != nil { 20 | fmt.Println("This value is not an integer:", number) 21 | } else { 22 | switch { 23 | case number < 0: 24 | fmt.Println("Less than zero!") 25 | case number > 0: 26 | fmt.Println("Bigger than zero!") 27 | default: 28 | fmt.Println("Zero!") 29 | } 30 | } 31 | 32 | asString := arguments[1] 33 | switch asString { 34 | case "5": 35 | fmt.Println("Five!") 36 | case "0": 37 | fmt.Println("Zero!") 38 | default: 39 | fmt.Println("Do not care!") 40 | } 41 | 42 | var negative = regexp.MustCompile(`-`) 43 | var floatingPoint = regexp.MustCompile(`\d?\.\d`) 44 | var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`) 45 | 46 | switch { 47 | case negative.MatchString(asString): 48 | fmt.Println("Negative number") 49 | case floatingPoint.MatchString(asString): 50 | fmt.Println("Floating point!") 51 | case email.MatchString(asString): 52 | fmt.Println("It is an email!") 53 | fallthrough 54 | default: 55 | fmt.Println("Something else!") 56 | } 57 | 58 | var aType error = nil 59 | switch aType.(type) { 60 | case nil: 61 | fmt.Println("It is nil interface!") 62 | default: 63 | fmt.Println("Not nil interface!") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ch09/plNoRace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | var CLOSEA = false 12 | 13 | var DATA = make(map[int]bool) 14 | 15 | var signal chan struct{} 16 | 17 | func random(min, max int) int { 18 | return rand.Intn(max-min) + min 19 | } 20 | 21 | func first(min, max int, out chan<- int) { 22 | for { 23 | select { 24 | case <-signal: 25 | close(out) 26 | return 27 | case out <- random(min, max): 28 | } 29 | } 30 | } 31 | 32 | func second(out chan<- int, in <-chan int) { 33 | for x := range in { 34 | _, ok := DATA[x] 35 | if ok { 36 | signal <- struct{}{} 37 | } else { 38 | fmt.Print(x, " ") 39 | DATA[x] = true 40 | out <- x 41 | } 42 | } 43 | fmt.Println() 44 | close(out) 45 | } 46 | 47 | func third(in <-chan int) { 48 | var sum int 49 | sum = 0 50 | for x2 := range in { 51 | sum = sum + x2 52 | } 53 | fmt.Printf("The sum of the random numbers is %d.\n", sum) 54 | } 55 | 56 | func main() { 57 | if len(os.Args) != 3 { 58 | fmt.Println("Need two integer parameters!") 59 | return 60 | } 61 | 62 | n1, _ := strconv.Atoi(os.Args[1]) 63 | n2, _ := strconv.Atoi(os.Args[2]) 64 | if n1 > n2 { 65 | fmt.Printf("%d should be smaller than %d.\n", n1, n2) 66 | return 67 | } 68 | 69 | signal = make(chan struct{}) 70 | 71 | rand.Seed(time.Now().UnixNano()) 72 | A := make(chan int) 73 | B := make(chan int) 74 | 75 | go first(n1, n2, A) 76 | go second(B, A) 77 | third(B) 78 | } 79 | -------------------------------------------------------------------------------- /ch10/rwMutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | var Password = secret{password: "myPassword"} 11 | 12 | type secret struct { 13 | RWM sync.RWMutex 14 | password string 15 | } 16 | 17 | func Change(c *secret, pass string) { 18 | c.RWM.Lock() 19 | fmt.Println("LChange") 20 | time.Sleep(10 * time.Second) 21 | c.password = pass 22 | c.RWM.Unlock() 23 | } 24 | 25 | func show(c *secret) string { 26 | c.RWM.RLock() 27 | fmt.Print("show") 28 | time.Sleep(3 * time.Second) 29 | defer c.RWM.RUnlock() 30 | return c.password 31 | } 32 | 33 | func showWithLock(c *secret) string { 34 | c.RWM.Lock() 35 | fmt.Println("showWithLock") 36 | time.Sleep(3 * time.Second) 37 | defer c.RWM.Unlock() 38 | return c.password 39 | } 40 | 41 | func main() { 42 | var showFunction = func(c *secret) string { return "" } 43 | if len(os.Args) != 2 { 44 | fmt.Println("Using sync.RWMutex!") 45 | showFunction = show 46 | } else { 47 | fmt.Println("Using sync.Mutex!") 48 | showFunction = showWithLock 49 | } 50 | 51 | var waitGroup sync.WaitGroup 52 | 53 | fmt.Println("Pass:", showFunction(&Password)) 54 | for i := 0; i < 15; i++ { 55 | waitGroup.Add(1) 56 | go func() { 57 | defer waitGroup.Done() 58 | fmt.Println("Go Pass:", showFunction(&Password)) 59 | }() 60 | } 61 | 62 | go func() { 63 | waitGroup.Add(1) 64 | defer waitGroup.Done() 65 | Change(&Password, "123456") 66 | }() 67 | 68 | waitGroup.Wait() 69 | fmt.Println("Pass:", showFunction(&Password)) 70 | } 71 | -------------------------------------------------------------------------------- /ch04/rwXML.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "encoding/xml" 6 | "fmt" 7 | "os" 8 | ) 9 | 10 | type Record struct { 11 | Name string 12 | Surname string 13 | Tel []Telephone 14 | } 15 | 16 | type Telephone struct { 17 | Mobile bool 18 | Number string 19 | } 20 | 21 | func loadFromJSON(filename string, key interface{}) error { 22 | in, err := os.Open(filename) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | decodeJSON := json.NewDecoder(in) 28 | err = decodeJSON.Decode(key) 29 | if err != nil { 30 | return err 31 | } 32 | in.Close() 33 | return nil 34 | } 35 | 36 | func main() { 37 | arguments := os.Args 38 | if len(arguments) == 1 { 39 | fmt.Println("Please provide a filename!") 40 | return 41 | } 42 | 43 | filename := arguments[1] 44 | 45 | var myRecord Record 46 | err := loadFromJSON(filename, &myRecord) 47 | if err == nil { 48 | fmt.Println("JSON:", myRecord) 49 | } else { 50 | fmt.Println(err) 51 | } 52 | 53 | myRecord.Name = "Dimitris" 54 | 55 | xmlData, _ := xml.MarshalIndent(myRecord, "", " ") 56 | xmlData = []byte(xml.Header + string(xmlData)) 57 | fmt.Println("\nxmlData:", string(xmlData)) 58 | 59 | data := &Record{} 60 | err = xml.Unmarshal(xmlData, data) 61 | if nil != err { 62 | fmt.Println("Unmarshalling from XML", err) 63 | return 64 | } 65 | 66 | result, err := json.Marshal(data) 67 | if nil != err { 68 | fmt.Println("Error marshalling to JSON", err) 69 | return 70 | } 71 | 72 | _ = json.Unmarshal([]byte(result), &myRecord) 73 | fmt.Println("\nJSON:", myRecord) 74 | } 75 | -------------------------------------------------------------------------------- /ch11/writingBU.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | var BUFFERSIZE int 11 | var FILESIZE int 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func createBuffer(buf *[]byte, count int) { 18 | *buf = make([]byte, count) 19 | if count == 0 { 20 | return 21 | } 22 | 23 | for i := 0; i < count; i++ { 24 | intByte := byte(random(0, 100)) 25 | if len(*buf) > count { 26 | return 27 | } 28 | *buf = append(*buf, intByte) 29 | } 30 | } 31 | 32 | func Create(dst string, b, f int) error { 33 | _, err := os.Stat(dst) 34 | if err == nil { 35 | return fmt.Errorf("File %s already exists.", dst) 36 | } 37 | 38 | destination, err := os.Create(dst) 39 | if err != nil { 40 | return err 41 | } 42 | defer destination.Close() 43 | 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | buf := make([]byte, 0) 49 | for { 50 | createBuffer(&buf, b) 51 | buf = buf[:b] 52 | if _, err := destination.Write(buf); err != nil { 53 | return err 54 | } 55 | 56 | if f < 0 { 57 | break 58 | } 59 | f = f - len(buf) 60 | } 61 | return err 62 | } 63 | 64 | func main() { 65 | if len(os.Args) != 3 { 66 | fmt.Println("Need BUFFERSIZE FILESIZE!") 67 | return 68 | } 69 | 70 | output := "/tmp/randomFile" 71 | BUFFERSIZE, _ = strconv.Atoi(os.Args[1]) 72 | FILESIZE, _ = strconv.Atoi(os.Args[2]) 73 | err := Create(output, BUFFERSIZE, FILESIZE) 74 | if err != nil { 75 | fmt.Println(err) 76 | } 77 | 78 | err = os.Remove(output) 79 | if err != nil { 80 | fmt.Println(err) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ch05/queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | var size = 0 13 | var queue = new(Node) 14 | 15 | func Push(t *Node, v int) bool { 16 | if queue == nil { 17 | queue = &Node{v, nil} 18 | size++ 19 | return true 20 | } 21 | 22 | t = &Node{v, nil} 23 | t.Next = queue 24 | queue = t 25 | size++ 26 | 27 | return true 28 | } 29 | 30 | func Pop(t *Node) (int, bool) { 31 | if size == 0 { 32 | return 0, false 33 | } 34 | 35 | if size == 1 { 36 | queue = nil 37 | size-- 38 | return t.Value, true 39 | } 40 | 41 | temp := t 42 | for (t.Next) != nil { 43 | temp = t 44 | t = t.Next 45 | } 46 | 47 | v := (temp.Next).Value 48 | temp.Next = nil 49 | 50 | size-- 51 | return v, true 52 | } 53 | 54 | func traverse(t *Node) { 55 | if size == 0 { 56 | fmt.Println("Empty Queue!") 57 | return 58 | } 59 | 60 | for t != nil { 61 | fmt.Printf("%d -> ", t.Value) 62 | t = t.Next 63 | } 64 | fmt.Println() 65 | } 66 | 67 | func main() { 68 | queue = nil 69 | Push(queue, 10) 70 | fmt.Println("Size:", size) 71 | traverse(queue) 72 | 73 | v, b := Pop(queue) 74 | if b { 75 | fmt.Println("Pop:", v) 76 | } 77 | fmt.Println("Size:", size) 78 | 79 | for i := 0; i < 5; i++ { 80 | Push(queue, i) 81 | } 82 | traverse(queue) 83 | fmt.Println("Size:", size) 84 | 85 | v, b = Pop(queue) 86 | if b { 87 | fmt.Println("Pop:", v) 88 | } 89 | fmt.Println("Size:", size) 90 | 91 | v, b = Pop(queue) 92 | if b { 93 | fmt.Println("Pop:", v) 94 | } 95 | fmt.Println("Size:", size) 96 | traverse(queue) 97 | } 98 | -------------------------------------------------------------------------------- /ch12/advancedWebClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 17 | return 18 | } 19 | 20 | URL, err := url.Parse(os.Args[1]) 21 | if err != nil { 22 | fmt.Println("Error in parsing:", err) 23 | return 24 | } 25 | 26 | c := &http.Client{ 27 | Timeout: 15 * time.Second, 28 | } 29 | request, err := http.NewRequest(http.MethodGet, URL.String(), nil) 30 | if err != nil { 31 | fmt.Println("Get:", err) 32 | return 33 | } 34 | 35 | httpData, err := c.Do(request) 36 | if err != nil { 37 | fmt.Println("Error in Do():", err) 38 | return 39 | } 40 | 41 | fmt.Println("Status code:", httpData.Status) 42 | header, _ := httputil.DumpResponse(httpData, false) 43 | fmt.Print(string(header)) 44 | 45 | contentType := httpData.Header.Get("Content-Type") 46 | characterSet := strings.SplitAfter(contentType, "charset=") 47 | if len(characterSet) > 1 { 48 | fmt.Println("Character Set:", characterSet[1]) 49 | } 50 | 51 | if httpData.ContentLength == -1 { 52 | fmt.Println("ContentLength is unknown!") 53 | } else { 54 | fmt.Println("ContentLength:", httpData.ContentLength) 55 | } 56 | 57 | length := 0 58 | var buffer [1024]byte 59 | r := httpData.Body 60 | for { 61 | n, err := r.Read(buffer[0:]) 62 | if err != nil { 63 | fmt.Println(err) 64 | break 65 | } 66 | length = length + n 67 | } 68 | fmt.Println("Calculated response data length:", length) 69 | } 70 | -------------------------------------------------------------------------------- /ch04/changeDT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "regexp" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | arguments := os.Args 15 | if len(arguments) == 1 { 16 | fmt.Println("Please provide one text file to process!") 17 | os.Exit(1) 18 | } 19 | 20 | filename := arguments[1] 21 | f, err := os.Open(filename) 22 | if err != nil { 23 | fmt.Printf("error opening file %s", err) 24 | os.Exit(1) 25 | } 26 | defer f.Close() 27 | 28 | notAMatch := 0 29 | r := bufio.NewReader(f) 30 | for { 31 | line, err := r.ReadString('\n') 32 | if err == io.EOF { 33 | break 34 | } else if err != nil { 35 | fmt.Printf("error reading file %s", err) 36 | } 37 | 38 | r1 := regexp.MustCompile(`.*\[(\d\d\/\w+/\d\d\d\d:\d\d:\d\d:\d\d.*)\] .*`) 39 | if r1.MatchString(line) { 40 | match := r1.FindStringSubmatch(line) 41 | d1, err := time.Parse("02/Jan/2006:15:04:05 -0700", match[1]) 42 | if err == nil { 43 | newFormat := d1.Format(time.Stamp) 44 | fmt.Print(strings.Replace(line, match[1], newFormat, 1)) 45 | } else { 46 | notAMatch++ 47 | } 48 | continue 49 | } 50 | 51 | r2 := regexp.MustCompile(`.*\[(\w+\-\d\d-\d\d:\d\d:\d\d:\d\d.*)\] .*`) 52 | if r2.MatchString(line) { 53 | match := r2.FindStringSubmatch(line) 54 | d1, err := time.Parse("Jan-02-06:15:04:05 -0700", match[1]) 55 | if err == nil { 56 | newFormat := d1.Format(time.Stamp) 57 | fmt.Print(strings.Replace(line, match[1], newFormat, 1)) 58 | } else { 59 | notAMatch++ 60 | } 61 | continue 62 | } 63 | } 64 | fmt.Println(notAMatch, "lines did not match!") 65 | } 66 | -------------------------------------------------------------------------------- /ch11/benchmarkMe_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var result int 8 | 9 | func benchmarkfibo1(b *testing.B, n int) { 10 | var r int 11 | for i := 0; i < b.N; i++ { 12 | r = fibo1(n) 13 | } 14 | result = r 15 | } 16 | 17 | func benchmarkfibo2(b *testing.B, n int) { 18 | var r int 19 | for i := 0; i < b.N; i++ { 20 | r = fibo2(n) 21 | } 22 | result = r 23 | } 24 | 25 | func benchmarkfibo3(b *testing.B, n int) { 26 | var r int 27 | for i := 0; i < b.N; i++ { 28 | r = fibo3(n) 29 | } 30 | result = r 31 | } 32 | 33 | func Benchmark30fibo1(b *testing.B) { 34 | benchmarkfibo1(b, 30) 35 | } 36 | 37 | func Benchmark30fibo2(b *testing.B) { 38 | benchmarkfibo2(b, 30) 39 | } 40 | 41 | func Benchmark30fibo3(b *testing.B) { 42 | benchmarkfibo3(b, 30) 43 | } 44 | 45 | func Benchmark50fibo1(b *testing.B) { 46 | benchmarkfibo1(b, 50) 47 | } 48 | 49 | func Benchmark50fibo2(b *testing.B) { 50 | benchmarkfibo2(b, 50) 51 | } 52 | 53 | func Benchmark50fibo3(b *testing.B) { 54 | benchmarkfibo3(b, 50) 55 | } 56 | 57 | // This is a correct benchmark function 58 | func BenchmarkFiboIV(b *testing.B) { 59 | for i := 0; i < b.N; i++ { 60 | _ = fibo3(10) 61 | } 62 | } 63 | 64 | // This is also a correct benchmark function 65 | func BenchmarkFiboIII(b *testing.B) { 66 | _ = fibo3(b.N) 67 | } 68 | 69 | // This benchmark function never converges 70 | // func BenchmarkFiboI(b *testing.B) { 71 | // for i := 0; i < b.N; i++ { 72 | // _ = fibo1(i) 73 | // } 74 | // } 75 | 76 | // This benchmark function never converges 77 | // func BenchmarkFiboII(b *testing.B) { 78 | // for i := 0; i < b.N; i++ { 79 | // _ = fibo2(b.N) 80 | // } 81 | // } 82 | -------------------------------------------------------------------------------- /ch06/htmlT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | _ "github.com/mattn/go-sqlite3" 7 | "html/template" 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | type Entry struct { 13 | Number int 14 | Double int 15 | Square int 16 | } 17 | 18 | var DATA []Entry 19 | var tFile string 20 | 21 | func myHandler(w http.ResponseWriter, r *http.Request) { 22 | fmt.Printf("Host: %s Path: %s\n", r.Host, r.URL.Path) 23 | myT := template.Must(template.ParseGlob(tFile)) 24 | myT.ExecuteTemplate(w, tFile, DATA) 25 | } 26 | 27 | func main() { 28 | arguments := os.Args 29 | if len(arguments) != 3 { 30 | fmt.Println("Need Database File + Template File!") 31 | return 32 | } 33 | 34 | database := arguments[1] 35 | tFile = arguments[2] 36 | 37 | db, err := sql.Open("sqlite3", database) 38 | if err != nil { 39 | fmt.Println(nil) 40 | return 41 | } 42 | 43 | fmt.Println("Emptying database table.") 44 | _, err = db.Exec("DELETE FROM data") 45 | if err != nil { 46 | fmt.Println(nil) 47 | return 48 | } 49 | 50 | fmt.Println("Populating", database) 51 | stmt, _ := db.Prepare("INSERT INTO data(number, double, square) values(?,?,?)") 52 | for i := 20; i < 50; i++ { 53 | _, _ = stmt.Exec(i, 2*i, i*i) 54 | } 55 | 56 | rows, err := db.Query("SELECT * FROM data") 57 | if err != nil { 58 | fmt.Println(nil) 59 | return 60 | } 61 | 62 | var n int 63 | var d int 64 | var s int 65 | for rows.Next() { 66 | err = rows.Scan(&n, &d, &s) 67 | temp := Entry{Number: n, Double: d, Square: s} 68 | DATA = append(DATA, temp) 69 | } 70 | 71 | http.HandleFunc("/", myHandler) 72 | err = http.ListenAndServe(":8080", nil) 73 | if err != nil { 74 | fmt.Println(err) 75 | return 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ch10/workerPool.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | type Client struct { 12 | id int 13 | integer int 14 | } 15 | 16 | type Data struct { 17 | job Client 18 | square int 19 | } 20 | 21 | var ( 22 | size = 10 23 | clients = make(chan Client, size) 24 | data = make(chan Data, size) 25 | ) 26 | 27 | func worker(w *sync.WaitGroup) { 28 | for c := range clients { 29 | square := c.integer * c.integer 30 | output := Data{c, square} 31 | data <- output 32 | time.Sleep(time.Second) 33 | } 34 | w.Done() 35 | } 36 | 37 | func makeWP(n int) { 38 | var w sync.WaitGroup 39 | for i := 0; i < n; i++ { 40 | w.Add(1) 41 | go worker(&w) 42 | } 43 | w.Wait() 44 | close(data) 45 | } 46 | 47 | func create(n int) { 48 | for i := 0; i < n; i++ { 49 | c := Client{i, i} 50 | clients <- c 51 | } 52 | close(clients) 53 | } 54 | 55 | func main() { 56 | fmt.Println("Capacity of clients:", cap(clients)) 57 | fmt.Println("Capacity of data:", cap(data)) 58 | 59 | if len(os.Args) != 3 { 60 | fmt.Println("Need #jobs and #workers!") 61 | return 62 | } 63 | 64 | nJobs, err := strconv.Atoi(os.Args[1]) 65 | if err != nil { 66 | fmt.Println(err) 67 | return 68 | } 69 | 70 | nWorkers, err := strconv.Atoi(os.Args[2]) 71 | if err != nil { 72 | fmt.Println(err) 73 | return 74 | } 75 | 76 | go create(nJobs) 77 | finished := make(chan interface{}) 78 | go func() { 79 | for d := range data { 80 | fmt.Printf("Client ID: %d\tint: ", d.job.id) 81 | fmt.Printf("%d\tsquare: %d\n", d.job.integer, d.square) 82 | } 83 | finished <- true 84 | }() 85 | 86 | makeWP(nWorkers) 87 | fmt.Printf(": %v\n", <-finished) 88 | } 89 | --------------------------------------------------------------------------------