├── .gitignore ├── GoLangVirtualHost.md ├── README.md ├── advance.md ├── advance_terms.md ├── assets__ ├── css │ └── style.txt └── img │ └── wanna_smile.png ├── bash_automation_28-09-2021 ├── benchmark.md ├── bitshifting.md ├── books ├── 9. variable .pdf ├── Ch-1(How computer works)-UPDATE.pdf ├── Ch-2(data_type)-UPDATE.pdf ├── Ch-3(hardware & software) update.pdf ├── Ch-4(what is programming)-UPDATE.pdf ├── Ch-5(ASCII table)-UPDATE.pdf ├── Ch-6 (file_folder)-UPDATE.pdf └── readme.md ├── breaknumbers.md ├── channel.md ├── closure.md ├── concurrency.md ├── database.md ├── db.md ├── galaxyshop.exe ├── generics.md ├── go.mod ├── go.sum ├── golang_find_replace.md ├── gotracer.md ├── groupby.md ├── http2.md ├── interface.md ├── ip.md ├── jwt.md ├── load.md ├── main.go ├── messagebroker.md ├── multipart.md ├── mutex.md ├── os.md ├── pool.md ├── race.md ├── recursive.md ├── reflect.md ├── router.md ├── smpp.md ├── smpp_27-09-2021 ├── students.txt ├── tcp.md ├── template ├── about.gohtml ├── footer.gohtml ├── header.gohtml └── index.gohtml ├── terms.md ├── tooling.md ├── usql.md └── videoedit.md /.gitignore: -------------------------------------------------------------------------------- 1 | .exe -------------------------------------------------------------------------------- /GoLangVirtualHost.md: -------------------------------------------------------------------------------- 1 | # How to provide the virtual hosts functionality using golang 2 | 3 | ```go 4 | 5 | package main 6 | 7 | import( 8 | "net/url" 9 | "net/http" 10 | "net/http/httputil" 11 | ) 12 | 13 | func main() { 14 | vhost1, err := url.Parse("http://127.0.0.1:1980") 15 | if err != nil { 16 | panic(err) 17 | } 18 | proxy1 := httputil.NewSingleHostReverseProxy(vhost1) 19 | http.HandleFunc("publicdomain1.com/", handler(proxy1)) 20 | 21 | vhost2, err := url.Parse("http://127.0.0.1:1981") 22 | if err != nil { 23 | panic(err) 24 | } 25 | proxy2 := httputil.NewSingleHostReverseProxy(vhost2) 26 | http.HandleFunc("publicdomain2.com/", handler(proxy2)) 27 | 28 | err = http.ListenAndServe(":80", nil) 29 | if err != nil { 30 | panic(err) 31 | } 32 | } 33 | 34 | func handler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) { 35 | return func(w http.ResponseWriter, r *http.Request) { 36 | p.ServeHTTP(w, r) 37 | } 38 | } 39 | 40 | ``` 41 | 42 | ## Resource 43 | * https://stackoverflow.com/questions/14170799/how-to-get-virtualhost-functionality-in-go 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang 2 | ## Golang Learning resources 3 | > Software engineering is a craft that should be honed, debated, and continuously improved. 4 | 5 | ## Golang Installation or Upgradation 6 | > go version \ 7 | > which go 8 | 9 | 10 | > wget https://go.dev/dl/go1.17.7.linux-amd64.tar.gz 11 | 12 | > sudo rm -rf /usr/local/go 13 | 14 | > sudo tar -xzf go1.17.7.linux-amd64.tar.gz 15 | 16 | > sudo mv go /usr/local 17 | 18 | > export PATH=$PATH:/usr/local/go/bin 19 | 20 | > source $HOME/.profile 21 | 22 | > go version 23 | 24 | 25 | ## Data type detection 26 | dataFields interface{} 27 | > dtype := reflect.TypeOf(dataFields).Kind().String() 28 | 29 | var c Company 30 | > fmt.Println(reflect.ValueOf(&c).Kind().String()) //ptr \ 31 | > fmt.Println(reflect.ValueOf([]string{"aid", "cid", "type"}).Kind().String()) //slice 32 | 33 | ## How to get the name of a struct? 34 | ```go 35 | func structName(myvar interface{}) string { 36 | if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr { 37 | return t.Elem().Name() 38 | } else { 39 | return t.Name() 40 | } 41 | } 42 | 43 | type Achead struct{ 44 | ID int 45 | Code string 46 | } 47 | 48 | fmt.Println(structName(Achead{})) 49 | fmt.Println(structName(&Achead{})) //Achead 50 | ``` 51 | 52 | ## Linux terminal build for windows 53 | > `Syntax: env GOOS=target-OS GOARCH=target-architecture go build package-import-path`\ 54 | > $ env GOOS=windows go build 55 | 56 | ## Windows terminal build 57 | > set GOOS=linux\ 58 | > go build -o appName 59 | 60 | ## Windows powershell build 61 | If you're using PowerShell, then changing values of environment variables should be done like: `$Env: = ""` 62 | 63 | > $Env:GOOS = "linux"; $Env:GOARCH = "amd64"; go build -o hello 64 | 65 | > `$Env:GOOS="linux";$Env:GOARCH="amd64"; go build -ldflags '-w -s'` 66 | 67 | ### Cache clean command 68 | > go clean --cache 69 | 70 | ### Trouble-shooting 71 | Cleaning the go caches once fixed some “unknown import path”/“cannot find module providing package” errors 72 | > go clean -cache -modcache -i -r 73 | 74 | ### Testing command 75 | > $Env:GOOS="windows";go test .\utility\ 76 | 77 | > `$Env:GOOS="windows";go test -timeout 30s -run ^TestSsPLNT$ graphmysql/utility` 78 | 79 | > $Env:GOOS="windows";go test ./... 80 | 81 | ## Golang How to upgrade to Go 1.17 82 | > go mod tidy -go=1.17 83 | > go mod edit -go 1.20 84 | 85 | ## Module on by default 86 | > go env -w GO111MODULE=auto 87 | 88 | > fmt.Println("NumGoroutine:", runtime.NumGoroutine()) \ 89 | > GODEBUG=gctrace=1 ./chaldal 90 | 91 | ## Go Module Create 92 | > `mkdir encdec && cd encdec` \ 93 | > `go mod init mateors.com/encdec` \ 94 | > write your source code & save the file 95 | 96 | ### This command deletes the cache downloaded along with unpacked code dependencies 97 | > go clean -modcache 98 | 99 | ## Go Module, Call your code from anothe module 100 | ```go 101 | import ( 102 | ... 103 | "mateors.com/encdec" 104 | ) 105 | ``` 106 | > go mod edit -replace mateors.com/encdec=../encdec \ 107 | > go get mateors.com/encdec 108 | 109 | ## Resource 110 | * https://golang.org/doc/tutorial/call-module-code 111 | * https://go.dev/blog/go116-module-changes 112 | * https://maelvls.dev/go111module-everywhere/ 113 | * https://hasura.io/graphql/database/ 114 | * https://nats.io/ 115 | * https://github.com/hasura/graphql-engine 116 | * https://hasura.io/graphql/database/ 117 | * https://lecstor.com/go-cheatsheet 118 | * https://github.com/boyter/scc 119 | -------------------------------------------------------------------------------- /advance.md: -------------------------------------------------------------------------------- 1 | # Advance Golang 2 | 3 | ## FreeOSMemory 4 | Go is a garbage collected language, which means that memory allocated and used by variables is automatically freed by the garbage collector when those variables become unreachable (if you have another pointer to the variable, that still counts as "reachable"). 5 | 6 | Freed memory does not mean it is returned to the OS. Freed memory means the memory can be reclaimed, reused for another variable if there is a need. So from the operating system you won't see memory decreasing right away just because some variable became unreachable and the garbage collector detected this and freed memory used by it. 7 | 8 | The Go runtime will however return memory to the OS if it is not used for some time (which is usually around 5 minutes). If the memory usage increases during this period (and optionally shrinks again), the memory will most likely not be returned to the OS. 9 | 10 | If you wait some time and not allocate memory again, freed memory will be returned to the OS eventually (obviously not all, but unused "big chunks" will be). If you can't wait for this to happen, you may call debug.FreeOSMemory() to force this behavior: 11 | 12 | ### How long should i wait to check how much memory is freed? 13 | you should wait at least 7 minutes to check how much memory is freed. Sometimes it needs two GC passes, so it would be 9 minutes. 14 | If that is not working, or it is too much time, you can add a periodic call to FreeOSMemory (no need to call runtime.GC() before, it is done by debug.FreeOSMemory() ) 15 | 16 | ```go 17 | package main 18 | 19 | import ( 20 | "runtime/debug" 21 | "time" 22 | ) 23 | 24 | func main() { 25 | 26 | go periodicFree(1 * time.Minute) 27 | // Your program goes here 28 | } 29 | 30 | func periodicFree(d time.Duration) { 31 | tick := time.Tick(d) 32 | for _ = range tick { 33 | debug.FreeOSMemory() 34 | } 35 | } 36 | 37 | ``` 38 | 39 | * [FreeOSMemory](https://pkg.go.dev/runtime/debug#FreeOSMemory) forces a garbage collection followed by an attempt to return as much memory to the operating system as possible. 40 | * Keep in mind that it won't do anything unless the GC has been run 41 | * The amount of memory released shown by runtime.ReadMemStats 42 | 43 | ## Topics 44 | * [Interface](https://github.com/mateors/golang/tree/interface) 45 | * Pointer 46 | * Singleflight | Mutex | Sync 47 | * Bitwise operator | Left shift | right shift 48 | * Goroutine 49 | * Channel | Select 50 | * Race condition | [Race tracer](https://pkg.go.dev/runtime/trace#Start) 51 | * Context 52 | 53 | > Package singleflight provides a duplicate function call suppression 54 | 55 | > go doc & go tool usage details 56 | 57 | ## How do we call function by its name (string) 58 | 59 | ```golang 60 | 61 | package main 62 | 63 | import "fmt" 64 | 65 | func someFunction1(a, b int) int { 66 | return a + b 67 | } 68 | 69 | func someFunction2(a, b int) int { 70 | return a - b 71 | } 72 | 73 | func someOtherFunction(a, b int, f func(int, int) int) int { 74 | return f(a, b) 75 | } 76 | 77 | func main() { 78 | 79 | //Method -1 80 | fmt.Println(someOtherFunction(111, 12, someFunction1)) 81 | fmt.Println(someOtherFunction(111, 12, someFunction2)) 82 | 83 | //Method-2 84 | m := map[string]func(int, int) int { 85 | "someFunction1": someFunction1, 86 | "someFunction2": someFunction2, 87 | } 88 | z := someOtherFunction(x, y, m[key]) 89 | fmt.Println(z) 90 | 91 | } 92 | ``` 93 | ## Struct to Fields (Embedded type included) 94 | 95 | ```go 96 | 97 | var tagGetName string = "json" //bson|msgpack 98 | 99 | func StructToFields(anyStruct interface{}) map[string]map[string]interface{} { 100 | 101 | stype := reflect.TypeOf(anyStruct) 102 | sf := structFields(stype) 103 | return structFieldMap(sf) 104 | } 105 | 106 | func structFieldMap(sf []reflect.StructField) map[string]map[string]interface{} { 107 | 108 | rmap := make(map[string]map[string]interface{}) 109 | for i, field := range sf { 110 | valm := make(map[string]interface{}) 111 | valm["name"] = field.Name 112 | valm["rtype"] = field.Type.String() //reflect.Type 113 | valm["tag"] = field.Tag.Get(tagGetName) 114 | valm["isexported"] = field.IsExported() 115 | valm["position"] = i 116 | //valm["anonymous"] = field.Anonymous //if embedded type then true 117 | rmap[field.Name] = valm 118 | } 119 | return rmap 120 | } 121 | 122 | func structFields(stype reflect.Type) []reflect.StructField { 123 | 124 | sf := make([]reflect.StructField, 0) 125 | if stype.Kind() == reflect.Pointer { 126 | stype = stype.Elem() 127 | } 128 | if stype.Kind() == reflect.Struct { 129 | for i := 0; i < stype.NumField(); i++ { 130 | f := stype.Field(i) 131 | if f.Anonymous { 132 | rtype := f.Type 133 | rs := structFields(rtype) 134 | sf = append(sf, rs...) 135 | } else { 136 | sf = append(sf, f) 137 | } 138 | } 139 | } 140 | return sf 141 | } 142 | ``` 143 | 144 | ## Usage example 145 | ```go 146 | type People struct{ 147 | Name string `json:"name"` 148 | Dob string `json:"dob"` 149 | Height float64 `json:"height"` 150 | } 151 | 152 | type Employee struct{ 153 | People 154 | Salary float64 155 | Status int 156 | } 157 | 158 | //struct 159 | emp := Employee{} 160 | rmap := StructToFields(emp) 161 | for key, val := range rmap { 162 | fmt.Println(key, val) 163 | } 164 | 165 | //pointer to struct 166 | emp2 := &Employee{} 167 | rmap = StructToFields(emp2) 168 | for key, val := range rmap { 169 | fmt.Println(key, val) 170 | } 171 | ``` 172 | 173 | ## Form filler | Form + StructReference = StructPropertyWithValue 174 | ```go 175 | func structFiller(form url.Values, anyStructToPointer interface{}) error { 176 | 177 | empv := reflect.ValueOf(anyStructToPointer) //must be a pointer 178 | empt := reflect.TypeOf(anyStructToPointer) // 179 | 180 | if empv.Kind() != reflect.Pointer { 181 | return errors.New("anyStructToPointer must be a pointer") 182 | } 183 | 184 | for i := 0; i < empv.Elem().NumField(); i++ { 185 | 186 | var vField reflect.Value 187 | var sField reflect.StructField 188 | 189 | vField = empv.Elem().Field(i) 190 | if empt.Kind() == reflect.Struct { 191 | sField = empt.Field(i) 192 | } 193 | 194 | if empt.Kind() == reflect.Pointer { 195 | sField = empt.Elem().Field(i) //? 196 | } 197 | 198 | fieldValue := structFieldValue(sField, "json") 199 | fvalue := form.Get(fieldValue) 200 | valueSet(vField, fvalue) // 201 | 202 | if sField.Type.Kind() == reflect.Struct { 203 | for j := 0; j < vField.NumField(); j++ { 204 | ssField := sField.Type.Field(j) 205 | fieldValue := structFieldValue(ssField, "json") 206 | fvalue := form.Get(fieldValue) 207 | valueSet(vField.Field(j), fvalue) 208 | } 209 | } 210 | } 211 | return nil 212 | } 213 | 214 | func valueSet(vField reflect.Value, fvalue interface{}) { 215 | 216 | if vField.Kind() == reflect.String { 217 | vField.SetString(fmt.Sprint(fvalue)) 218 | 219 | } else if vField.Kind() == reflect.Int64 { 220 | fvalueInt, _ := strconv.ParseInt(fmt.Sprint(fvalue), 10, 64) 221 | vField.SetInt(fvalueInt) 222 | 223 | } else if vField.Kind() == reflect.Int { 224 | fvalueInt, _ := strconv.ParseInt(fmt.Sprint(fvalue), 10, 64) 225 | vField.SetInt(fvalueInt) 226 | 227 | } else if vField.Kind() == reflect.Float64 { 228 | fvalueInt, _ := strconv.ParseFloat(fmt.Sprint(fvalue), 64) 229 | vField.SetFloat(fvalueInt) 230 | 231 | } else if vField.Kind() == reflect.Bool { 232 | boolVal, _ := strconv.ParseBool(fmt.Sprint(fvalue)) 233 | vField.SetBool(boolVal) 234 | 235 | } else if vField.Kind() == reflect.Slice { 236 | vslc := strings.Split(fmt.Sprint(fvalue), ",") 237 | var strValue reflect.Value = reflect.ValueOf(vslc) 238 | vField.Set(strValue) 239 | } 240 | } 241 | 242 | func structFieldValue(field reflect.StructField, tagField string) string { 243 | var fieldValue string = field.Tag.Get(tagField) 244 | if fieldValue == "" { 245 | fieldValue = strings.ToLower(field.Name) 246 | } 247 | return fieldValue 248 | } 249 | ``` 250 | 251 | ## Form filler usage example 252 | 253 | ```go 254 | 255 | type BasicInfo struct { 256 | Name string `json:"name"` 257 | Age int64 258 | Gender string 259 | } 260 | 261 | type Employee struct { 262 | BasicInfo 263 | Designation string 264 | Salary float64 265 | Adult bool 266 | Hobby []string 267 | Status int 268 | } 269 | 270 | form := make(url.Values) 271 | form.Set("name", "Wania") 272 | form.Set("age", "2") 273 | form.Set("gender", "female") 274 | form.Set("designation", "Engineer") 275 | form.Set("salary", "5000.50") 276 | form.Set("status", "1") 277 | form.Set("adult", "1") 278 | form.Set("hobby", "quran,reading,swimming") 279 | 280 | var emp Employee 281 | err := structFiller(form, &emp) //form + pointer to struct | struct reference 282 | fmt.Println(err) 283 | 284 | ``` 285 | 286 | ## Multilingual App 287 | * https://github.com/mateors/cloudcode 288 | 289 | 290 | ## Reference 291 | * https://stackoverflow.com/questions/18017979/golang-pointer-to-function-from-string-functions-name 292 | * https://mikespook.com/2012/07/function-call-by-name-in-golang/ 293 | 294 | ## Resource 295 | * [Bitshifting Basic video](https://www.youtube.com/watch?v=qq64FrA2UXQ) 296 | * https://github.com/yangchenxing/go-map2struct 297 | * https://github.com/yangchenxing/go-singleflight 298 | * [Map to Struct](https://github.com/mateors/go-map2struct) 299 | * [free-memory-once-occupied](https://stackoverflow.com/questions/37382600/cannot-free-memory-once-occupied-by-bytes-buffer) 300 | * [Full-text-search-engine](https://artem.krylysov.com/blog/2020/07/28/lets-build-a-full-text-search-engine) 301 | -------------------------------------------------------------------------------- /advance_terms.md: -------------------------------------------------------------------------------- 1 | # How do computers read code? 2 | * [How computers read code](https://www.youtube.com/watch?v=QXjU9qTsYCc) 3 | 4 | # Compile-link model 5 | compile-link model for generating executable binaries from the source code 6 | 7 | Creating an executable is a multistage process divided into two components: compilation and linking. In reality, even if a program "compiles fine" it might not actually work because of errors during the linking phase. The total process of going from source code files to an executable might better be referred to as a build. 8 | 9 | ## Compilation 10 | Compilation refers to the processing of source code files (.c, .cc, or .cpp) and the creation of an 'object' file. This step doesn't create anything the user can actually run. Instead, the compiler merely produces the machine language instructions that correspond to the source code file that was compiled. 11 | 12 | ## Linking 13 | the linker takes the object files produced by the compiler and produces either a library or an executable file. 14 | 15 | * [Compiling assembling and linking](https://www.youtube.com/watch?v=N2y6csonII4) 16 | * https://www.cprogramming.com/compilingandlinking.html 17 | -------------------------------------------------------------------------------- /assets__/css/style.txt: -------------------------------------------------------------------------------- 1 | css file -------------------------------------------------------------------------------- /assets__/img/wanna_smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/assets__/img/wanna_smile.png -------------------------------------------------------------------------------- /bash_automation_28-09-2021: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Special File Permissions (setuid, setgid and Sticky Bit) 4 | 5 | find directory -user root -perm -4000 -exec ls -ldb {} \; 6 | 7 | find / -user root -perm -4000 -exec ls -ldb {} \; 8 | 9 | # Reference: 10 | * https://docs.oracle.com/cd/E19683-01/816-4883/secfile-69/index.html 11 | * https://docs.oracle.com/cd/E19683-01/816-4883/6mb2joatb/index.html 12 | 13 | Every bash script starts with this string: “!#/bin/bash.” The exclamation point and hash symbol is known in the UNIX world as a “she-bang” and is the foundation of pretty much any UNIX-based script. 14 | 15 | 16 | 17 | double ampersand (&&)? That tells the script to execute one command right after the other. 18 | 19 | It also tells the script to stop if something goes wrong. If you used a single ampersand, the script would continue even if the first command failed. 20 | 21 | 22 | > sudo apt autoremove -y 23 | 24 | libfprint-2-tod1 libllvm10 25 | (Reading database ... 202619 files and directories currently installed.) 26 | 27 | 28 | ## Create a Shell Script to Install NGINX from Source On Ubuntu 29 | https://aaronluna.dev/blog/install-nginx-source-code-shell-script/ 30 | 31 | https://medium.com/@ayeshasilvia/how-to-automate-interactive-installation-on-linux-short-sweet-ac59b345f84f 32 | 33 | https://linuxhandbook.com/bash-automation/ 34 | 35 | 36 | https://code.tutsplus.com/tutorials/the-fundamentals-of-bash-scripting--net-32093 37 | 38 | https://gist.github.com/sheikhwaqas/9088872 39 | 40 | Reading database ... 202608 files and directories currently installed 41 | 42 | sudo apt install silversearcher-ag 43 | 44 | dpkg --list | wc --lines 45 | 46 | find . -maxdepth 1 -type f | wc -l 47 | 48 | I was curious to know which command actually causes this counting? The attempts I have made so far are: 49 | https://askubuntu.com/questions/923425/aptitude-count-number-of-files-and-directories 50 | 51 | ls -1 | wc -l 52 | 53 | cat /var/lib/dpkg/info/*.list | sort | uniq | wc -l 54 | 202662 55 | 56 | strings $(which dpkg) | grep "currently installed" 57 | 58 | dpkg --listfiles hello 59 | 60 | https://devconnected.com/how-to-count-files-in-directory-on-linux/ 61 | 62 | 63 | ## How To Find Largest Top 10 Files and Directories On Linux / UNIX / BSD 64 | https://www.cyberciti.biz/faq/how-do-i-find-the-largest-filesdirectories-on-a-linuxunixbsd-filesystem/ 65 | 66 | du -a /var | sort -n -r | head -n 10 67 | 68 | sudo du /var/ -h --max-depth=999 69 | 70 | Now, every command run in bash shell returns a value that’s stored in the bash variable “$?”. To get the value, run this command. 71 | 72 | 73 | echo $? 74 | If a command succeeded successfully, the return value will be 0. If the return value is otherwise, then it didn’t run as it’s supposed to 75 | 76 | 77 | ## single ampersand between 2 expressions 78 | This is the bitwise AND operator. 79 | 80 | -------------------------------------------------------------------------------- /benchmark.md: -------------------------------------------------------------------------------- 1 | ## Go Benchmark 2 | 3 | benchmark executed by the "go test" command when its -bench flag is provided. Benchmarks are run sequentially. 4 | 5 | ```go 6 | func BenchmarkRandInt(b *testing.B) { 7 | for i := 0; i < b.N; i++ { 8 | rand.Int() 9 | } 10 | } 11 | ``` 12 | 13 | > go test -run=TestFib -v 14 | 15 | > go test -run=xxx -v -bench=. 16 | 17 | > go test -run=xxx -v -bench=. -benchtime=3s 18 | 19 | ### Testing With Memory Allocation 20 | > go test -benchmem -run=^$ -bench ^BenchmarkSs* graphmysql/utility 21 | 22 | > go test -benchmem -bench ^BenchmarkSs* graphmysql/utility 23 | 24 | ### No testing only Benchmark with memory allocation 25 | > go test -run=^$ -benchmem -bench ^BenchmarkGetpass* graphmysql/utility 26 | 27 | ### Withour memory 28 | > go test -bench ^BenchmarkSs* graphmysql/utility 29 | -------------------------------------------------------------------------------- /bitshifting.md: -------------------------------------------------------------------------------- 1 | # Bit Shifting in Golang 2 | The Go programming language supports several bitwise operators including the followings: 3 | 4 | ``` 5 | & bitwise AND 6 | | bitwise OR 7 | ^ bitwise XOR 8 | &^ AND NOT 9 | << left shift 10 | >> right shift 11 | ``` 12 | 13 | 14 | ## Left Shifting 15 | 16 | ```go 17 | x := 7 //00000111 18 | fmt.Printf("%08b\n", x) 19 | fmt.Println(x, x<<1) //14 20 | fmt.Println(x, x<<2) //28 21 | fmt.Println(x, x<<3) //56 22 | fmt.Println(x, x<<4) //112 23 | ``` 24 | 25 | ## Manual Left shifting 26 | ```go 27 | fmt.Printf("%d\n", 0b00000111) //7 28 | fmt.Printf("%d\n", 0b00001110) //14 29 | fmt.Printf("%d\n", 0b00011100) //28 30 | fmt.Printf("%d\n", 0b00111000) //56 31 | fmt.Printf("%d\n", 0b01110000) //112 32 | fmt.Printf("%d\n", 0b11100000) //224 33 | ``` 34 | 35 | ## Right Shifting 36 | 37 | ```go 38 | fmt.Println(x, x>>1) //3 0b00000011 39 | fmt.Println(x, x>>2) //1 0b00000001 40 | fmt.Println(x, x>>3) //0 0b00000000 41 | ``` 42 | 43 | ```go 44 | func add(a, b int64) int64 { 45 | 46 | for b != 0 { 47 | 48 | // common bits of a and b go to carry 49 | carry := a & b 50 | 51 | // xor - sum bits where one is not set 52 | a = a ^ b 53 | 54 | // shift carry by 1 55 | b = carry << 1 56 | } 57 | return a 58 | } 59 | 60 | func subtract(a, b int64) int64 { 61 | 62 | for b != 0 { 63 | 64 | // common bits of a and b go to borrow 65 | borrow := ^a & b 66 | 67 | // xor - sum bits where one is not set 68 | a = a ^ b 69 | 70 | // shift borrow by 1 71 | b = borrow << 1 72 | } 73 | return a 74 | } 75 | 76 | ``` 77 | 78 | ## Resource 79 | * [Golang IOTA & Bitwise Bit Shifting](https://www.youtube.com/watch?v=FHEyulwEEdE) 80 | * [bit-manipulation-go](https://mariadesouza.com/2017/09/14/bit-manipulation-go) 81 | -------------------------------------------------------------------------------- /books/9. variable .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/9. variable .pdf -------------------------------------------------------------------------------- /books/Ch-1(How computer works)-UPDATE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-1(How computer works)-UPDATE.pdf -------------------------------------------------------------------------------- /books/Ch-2(data_type)-UPDATE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-2(data_type)-UPDATE.pdf -------------------------------------------------------------------------------- /books/Ch-3(hardware & software) update.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-3(hardware & software) update.pdf -------------------------------------------------------------------------------- /books/Ch-4(what is programming)-UPDATE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-4(what is programming)-UPDATE.pdf -------------------------------------------------------------------------------- /books/Ch-5(ASCII table)-UPDATE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-5(ASCII table)-UPDATE.pdf -------------------------------------------------------------------------------- /books/Ch-6 (file_folder)-UPDATE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/books/Ch-6 (file_folder)-UPDATE.pdf -------------------------------------------------------------------------------- /books/readme.md: -------------------------------------------------------------------------------- 1 | # Golang Programming Book 2 | -------------------------------------------------------------------------------- /breaknumbers.md: -------------------------------------------------------------------------------- 1 | # Break number into integer and fraction parts in Golang 2 | math package of golang provides a Modf method that can be used to break a floating-point number into integer and floating part. Please note that the integer part is also returned as a float by this function. 3 | 4 | ```go 5 | func Modf(f float64) (int float64, frac float64) 6 | ``` 7 | 8 | ## [Test code](https://go.dev/play/p/z9--C7BGw1u) 9 | 10 | ```go 11 | package main 12 | 13 | import ( 14 | "fmt" 15 | "math" 16 | ) 17 | 18 | func main() { 19 | floats := []float64{1.9999, 2.0001, 2.0} 20 | 21 | for _, f := range floats { 22 | 23 | //Contain both integer and fraction 24 | integer, fraction := math.Modf(f) 25 | fmt.Printf("Integer: %f. Fraction: %f\n", integer, fraction) 26 | 27 | } 28 | } 29 | ``` 30 | 31 | ## Output 32 | ``` 33 | Integer: 1.000000. Fraction: 0.999900 34 | Integer: 2.000000. Fraction: 0.000100 35 | Integer: 2.000000. Fraction: 0.000000 36 | ``` 37 | -------------------------------------------------------------------------------- /channel.md: -------------------------------------------------------------------------------- 1 | # Golang goroutine communication using channel 2 | 3 | ```go 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | var wg sync.WaitGroup 13 | 14 | func main() { 15 | 16 | //wg.Add(1) 17 | 18 | c1 := make(chan map[string]string, 1) //no wait required 19 | go sendMap(c1) 20 | //go receiveMap(c1) //finish this 21 | fmt.Println("Welcome", len(c1)) //then execute this line 22 | 23 | fmt.Println(<-c1) 24 | // for v := range c1 { 25 | // fmt.Println(v) 26 | // } 27 | //wg.Wait() 28 | 29 | } 30 | 31 | //send only or incoming 32 | func sendMap(cstr chan<- map[string]string) { 33 | 34 | //defer wg.Done() 35 | time.Sleep(time.Millisecond * 4000) 36 | nmap := map[string]string{ 37 | "name": "Mostain", 38 | "education": "CIS", 39 | } 40 | cstr <- nmap 41 | close(cstr) 42 | 43 | } 44 | 45 | //receive only 46 | func receiveMap(cstr <-chan map[string]string) { 47 | 48 | defer wg.Done() 49 | nmap := <-cstr 50 | for key, val := range nmap { 51 | fmt.Println(key, val) 52 | } 53 | 54 | } 55 | 56 | //send only 57 | func send(cstr chan<- string) { 58 | 59 | time.Sleep(time.Millisecond * 100) 60 | cstr <- "Hello" 61 | 62 | } 63 | 64 | //receive only 65 | func receive(cstr <-chan string) { 66 | 67 | msg := <-cstr 68 | fmt.Println(msg) 69 | 70 | } 71 | ``` 72 | 73 | ## Advance Channel without sync Package 74 | 75 | ```go 76 | package main 77 | 78 | import ( 79 | "fmt" 80 | "time" 81 | ) 82 | 83 | func main(){ 84 | 85 | rows := []map[string]interface{}{ 86 | {"name": "Mostain", "age": 38}, 87 | {"name": "Moaz", "age": 25}, 88 | {"name": "Nahid", "age": 26}, 89 | {"name": "Anonnya", "age": 27}, 90 | {"name": "Tareq", "age": 29}, 91 | {"name": "Eshita", "age": 27}, 92 | {"name": "Riyaz", "age": 21}, 93 | {"name": "Pallabi", "age": 21}, 94 | {"name": "Zubair", "age": 22}, 95 | {"name": "Sumi", "age": 30}, 96 | } 97 | c1 := make(chan []map[string]interface{}, 5) 98 | 99 | se := calcMaster(10, 2) 100 | for _, val := range se { 101 | go rowProcessor(c1, val, rows) 102 | 103 | } 104 | 105 | //time.Sleep(time.Millisecond * 100) 106 | var nmap = make([]map[string]interface{}, 0) 107 | for range se { 108 | vals := <-c1 109 | for _, row := range vals { 110 | nmap = append(nmap, row) 111 | } 112 | fmt.Println("receiver:", len(vals)) 113 | } 114 | 115 | close(c1) 116 | fmt.Println("Done!", len(nmap)) 117 | } 118 | 119 | //sender 120 | func rowProcessor(c chan<- []map[string]interface{}, sval *startEnd, rows []map[string]interface{}) { 121 | 122 | fmt.Println("sender:", sval.Start, sval.End) 123 | //time.Sleep(time.Millisecond * 5000) 124 | c <- rows[sval.Start:sval.End] 125 | } 126 | 127 | type startEnd struct { 128 | Start int 129 | End int 130 | } 131 | ``` 132 | 133 | -------------------------------------------------------------------------------- /closure.md: -------------------------------------------------------------------------------- 1 | # Golang Lazy Evaluation using closure 2 | > What is a closure in computing? \ 3 | In computer science, a closure is a function that has an environment of its own. In this environment, there is at least one bound variable (a name that has a value, such as a number). The closure's environment keeps the bound variables in memory between uses of the closure. 4 | 5 | ## Higher-order function 6 | In mathematics and computer science, a higher-order function is a function that does at least one of the following: takes one or more functions as arguments, returns a function as its result. All other functions are first-order functions. In mathematics higher-order functions are also termed operators or functionals. 7 | 8 | A Higher-Order function is a function that receives a function as an argument or returns the function as output. Higher order functions are functions that operate on other functions, either by taking them as arguments or by returning them. 9 | 10 | ```go 11 | package main 12 | 13 | import "fmt" 14 | 15 | func main() { 16 | 17 | igen := intGenerator() 18 | fmt.Println(">>", igen()) //2 19 | fmt.Println(">>", igen()) //4 20 | fmt.Println(">>", igen()) //6 21 | //igen = nil 22 | 23 | } 24 | 25 | type genType func() int 26 | 27 | func intGenerator() genType { 28 | x := 0 29 | return func() int { 30 | x += 2 31 | return x 32 | } 33 | } 34 | ``` 35 | ## Lazy Evaluation 36 | Lazy evaluation or non-strict evaluation is the process of delaying evaluation of an expression until it is needed. In general, Go does strict/eager evaluation but for operands like && and || it does a lazy evaluation. We can utilize higher-order-functions, closures, goroutines, and channels to emulate lazy evaluations. 37 | 38 | ## Lazy loading using sync.Once 39 | 40 | ```go 41 | 42 | package main 43 | 44 | import ( 45 | "fmt" 46 | "sync" 47 | ) 48 | 49 | type LazyInt func() int 50 | 51 | func Make(f func() int) LazyInt { 52 | var v int 53 | var once sync.Once 54 | return func() int { 55 | once.Do(func() { 56 | v = f() 57 | f = nil // so that f can now be GC'ed 58 | }) 59 | return v 60 | } 61 | } 62 | 63 | func main() { 64 | n := Make(func() int { return 23 }) // Or something more expensive… 65 | fmt.Println(n()) // Calculates the 23 66 | fmt.Println(n() + 42) // Reuses the calculated value 67 | } 68 | ``` 69 | 70 | ## [Lazy loading implementation using higher order functions](https://go.dev/play/p/Ty8vpd52TaI) 71 | ```go 72 | package main 73 | 74 | import "fmt" 75 | 76 | // a func(x int) int 77 | func Double(x int) int { 78 | return x * x 79 | } 80 | 81 | // a func(x, y int) int 82 | func Double2(x, y int) int { 83 | return x * y 84 | } 85 | 86 | // Double2 == func(x int) int, x int) int 87 | func ClosureFunc(a func(x, y int) int, x, y int) int { 88 | return a(x, y) 89 | } 90 | 91 | func main() { 92 | //fmt.Println(">>", ClosureFunc(Double, 5)) 93 | fmt.Println(">>", ClosureFunc(Double2, 5, 6)) 94 | } 95 | ``` 96 | ## Futures in Go 97 | Futures are mechanisms for decoupling a value from how it was computed. Goroutines and channels allow implementing futures trivially. 98 | ```go 99 | c := make(chan int) // future 100 | go func() { c <- f() }() // async 101 | value := <-c // await 102 | ``` 103 | 104 | ## Singleton Pattern in Go or sync.Once 105 | Just Call Your Code Only Once 106 | 107 | ```go 108 | package main 109 | 110 | import ( 111 | "fmt" 112 | "sync" 113 | ) 114 | 115 | type DbConnection struct{} 116 | 117 | var ( 118 | dbConnOnce sync.Once 119 | conn *DbConnection 120 | ) 121 | 122 | func GetConnection() *DbConnection { 123 | dbConnOnce.Do(func() { 124 | conn = &DbConnection{} 125 | fmt.Println("Inside") 126 | }) 127 | fmt.Println("Outside") 128 | return conn 129 | } 130 | 131 | func main() { 132 | for i := 0; i < 5; i++ { 133 | _ = GetConnection() 134 | } 135 | } 136 | //outputs 137 | Inside 138 | Outside 139 | Outside 140 | Outside 141 | Outside 142 | Outside 143 | ``` 144 | 145 | 146 | ## Resource 147 | * [Lazy evaluation](https://deepu.tech/functional-programming-in-go/) 148 | * [Go-Pipelines Lazy vs Eager](https://medium.com/@j.d.livni/understanding-go-pipelines-in-5-minutes-2906a5c41496) 149 | * [lazy-evaluation-in-go](https://blog.merovius.de/posts/2015-07-17-lazy-evaluation-in-go/) 150 | * [Futures in GO](https://appliedgo.net/futures/#:~:text=Futures%20in%20a%20nutshell,for%20Go's%20built%2Din%20concurrency.) 151 | * [Functional-Programming](https://deepu.tech/functional-programming-in-go/) 152 | * [Easy-functional-programming-techniques](https://dev.to/deepu105/7-easy-functional-programming-techniques-in-go-3idp) 153 | * [Thread-safe-lazy-loading](https://www.fareez.info/blog/thread-safe-lazy-loading-using-sync-once-in-go/) 154 | -------------------------------------------------------------------------------- /concurrency.md: -------------------------------------------------------------------------------- 1 | # Golang Concurrency 2 | 3 | ```go 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | func main() { 11 | 12 | c1 := make(chan string) 13 | c1<- "Mostain" //sending 14 | 15 | //code blocks here until something is ready to receive 16 | 17 | v := <-c1 //receiving 18 | fmt.Println(v) 19 | 20 | } 21 | ``` 22 | * The above won't run because of deadlock 23 | * Because of both are in the same goroutine 24 | 25 | You can fix the above problem in two ways 26 | 27 | ### Way-01, wrap the sending code in a separate goroutine 28 | ```go 29 | go func() { 30 | c1 <- "mostain" 31 | }() 32 | 33 | v := <-c1 34 | fmt.Println(v) 35 | ``` 36 | 37 | ### Way-02, using the buffered channel 38 | ```go 39 | c1 := make(chan string,1) //making a buffered channel by giving a capacity 40 | c1<- "Mostain" //sending 41 | 42 | v := <-c1 //receiving 43 | fmt.Println(v) 44 | 45 | ``` 46 | ### Channel select 47 | ```go 48 | package main 49 | 50 | import ( 51 | "fmt" 52 | "time" 53 | ) 54 | 55 | func main() { 56 | 57 | c1 := make(chan string) 58 | c2 := make(chan string) 59 | 60 | go func() { 61 | for i := 0; i < 3; i++ { 62 | c1 <- "worker1 every 500 ms" 63 | time.Sleep(time.Millisecond * 500) 64 | } 65 | }() 66 | 67 | go func() { 68 | 69 | for i := 0; i < 3; i++ { 70 | c2 <- "worker2 every 1.5 seconds" 71 | time.Sleep(time.Millisecond * 1500) 72 | } 73 | 74 | }() 75 | 76 | var counter int 77 | for { 78 | 79 | //fmt.Println(<-c1) 80 | //fmt.Println(<-c2) 81 | 82 | select { 83 | case msg1 := <-c1: 84 | fmt.Println(msg1) 85 | 86 | case msg2 := <-c2: 87 | fmt.Println(msg2) 88 | counter++ 89 | default: 90 | fmt.Println("none of them are ready to send") 91 | time.Sleep(time.Millisecond * 100) 92 | } 93 | 94 | //fmt.Println("counter:", counter) 95 | if counter == 3 { 96 | break 97 | } 98 | } 99 | 100 | } 101 | ``` 102 | 103 | ## Worker pool 104 | 105 | ```go 106 | package main 107 | 108 | import ( 109 | "fmt" 110 | ) 111 | 112 | func fib(n int) int { 113 | 114 | if n <= 1 { 115 | return n 116 | } 117 | return fib(n-1) + fib(n-2) 118 | } 119 | 120 | func worker(jobs <-chan int, result chan<- int) { 121 | 122 | for n := range jobs { 123 | result <- fib(n) 124 | } 125 | } 126 | 127 | func main() { 128 | 129 | jobs := make(chan int, 100) 130 | results := make(chan int, 100) 131 | 132 | go worker(jobs, results) 133 | go worker(jobs, results) 134 | go worker(jobs, results) 135 | go worker(jobs, results) 136 | go worker(jobs, results) 137 | go worker(jobs, results) 138 | go worker(jobs, results) 139 | go worker(jobs, results) 140 | go worker(jobs, results) 141 | go worker(jobs, results) 142 | go worker(jobs, results) 143 | go worker(jobs, results) 144 | 145 | for i := 0; i < 100; i++ { 146 | jobs <- i 147 | } 148 | close(jobs) 149 | 150 | for i := 0; i < 100; i++ { 151 | res := <-results 152 | fmt.Println(res) 153 | } 154 | 155 | } 156 | ``` 157 | 158 | 159 | ## Resource 160 | * [Get-a-taste-of-concurrency](https://levelup.gitconnected.com/get-a-taste-of-concurrency-in-go-625e4301810f) 161 | * [Multihreading-and-multiprocessing](https://www.mineiros.io/blog/guide-to-multihreading-and-multiprocessing) 162 | * [Common-mistakes or gotchas](https://www.linkedin.com/pulse/50-shades-go-traps-gotchas-common-mistakes-new-golang-okhotnikov-1f/) 163 | -------------------------------------------------------------------------------- /database.md: -------------------------------------------------------------------------------- 1 | # Golang Database Programming 2 | 3 | ## Learning Resource 4 | 5 | * [A-clean-way-to-implement-database-transaction-in-golang](https://dev.to/techschoolguru/a-clean-way-to-implement-database-transaction-in-golang-2ba) 6 | * [Backend master class](https://www.youtube.com/playlist?list=PLy_6D98if3ULEtXtNSY_2qN21VCKgoQAE) 7 | -------------------------------------------------------------------------------- /db.md: -------------------------------------------------------------------------------- 1 | # DB from scratch 2 | 3 | * [how-i-built-a-key-value-store-in-g](https://medium.com/@naqvi.jafar91/how-i-built-a-key-value-store-in-go-bd89f68062a8) 4 | * [pogreb-key-value-store](https://artem.krylysov.com/blog/2018/03/24/pogreb-key-value-store) 5 | * [full-text-search-engine](https://artem.krylysov.com/blog/2020/07/28/lets-build-a-full-text-search-engine) 6 | -------------------------------------------------------------------------------- /galaxyshop.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mateors/golang/246ef4719871ab4b610a22a8467254ea53ffd5e4/galaxyshop.exe -------------------------------------------------------------------------------- /generics.md: -------------------------------------------------------------------------------- 1 | # Golang introduces Generics in version 1.18 2 | 3 | ## What is Generics? 4 | Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create functions that work with different data types. 5 | 6 | With generics, you can declare and use functions or types that are written to work with any of a set of types provided by calling code. 7 | 8 | ## Why should i care about generics? 9 | You should care about generics because they mean you don’t have to write as much code, especially if you’re in the business of writing packages and tooling. It can be frustrating to write utility functions without generics support. Think about common data structures like binary search trees and linked lists. Why would you want to rewrite them for every type they could possibly contain? int, bool, float64, and string aren’t the end of the list, because you may want to store a custom struct type. 10 | 11 | Generics will finally give Go developers an elegant way to write amazing utility packages. 12 | 13 | ## Generics 3 main features 14 | * Type Parameter with constraints 15 | * Type Inference 16 | * Type Set 17 | 18 | ### 1. Type Parameter with constraints 19 | ```go 20 | package main 21 | import "fmt" 22 | 23 | func myFunc[T any](a T) T { 24 | return a 25 | } 26 | 27 | func main() { 28 | a := myFunc[int](10) 29 | fmt.Println(a) 30 | } 31 | 32 | ``` 33 | #### Calling above function 34 | ``` 35 | a:=myFunc[int](10) 36 | fmt.Println(a) 37 | ``` 38 | 39 | ### 2. Type Inference 40 | Inference is using observation and background to reach a logical conclusion. You probably practice inference every day. For example, if you see someone eating a new food and he or she makes a face, then you infer he does not like it. Or if someone slams a door, you can infer that she is upset about something. 41 | 42 | Inference: the process of inferring something. -> deduce or conclude -> remove type when calling a function 43 | 44 | > Calling differently according to the inference theory. 45 | ```go 46 | package main 47 | 48 | import "fmt" 49 | 50 | func myFunc[T any](a T) T { 51 | return a 52 | } 53 | 54 | // Any value with int64 or underlying type int64 are allowed 55 | // with the special symbol called tilde ~ 56 | // **Hints:** notice a tilde sign before int64 57 | func nextNumber[T ~int64 | float64](a T) T { 58 | return a + 1 59 | } 60 | 61 | type superInt int64 62 | 63 | func main() { 64 | 65 | a := myFunc[int](10) //calling with type 66 | fmt.Println("myFunc:", a) 67 | 68 | a = myFunc(10) //calling without type == type inference 69 | fmt.Println("myFunc withoutType:", a) 70 | 71 | b := nextNumber(5.0) 72 | fmt.Println("nextNumber:", b) 73 | 74 | var c superInt = 7 //superInt underlying type is int64 75 | d := nextNumber(c) //if you remove tilde sign from the function defination it wouldn't work. 76 | fmt.Println("~ nextNumber:", d) 77 | 78 | } 79 | 80 | ``` 81 | 82 | ### 3. Type Set (Declare a type constraint| Custom type) 83 | 84 | ```go 85 | package main 86 | 87 | import "fmt" 88 | 89 | type Number interface { 90 | ~float64 | int64 | int //Declare a union of int64 and float64 inside the interface. 91 | } 92 | 93 | type Price float64 94 | 95 | func nextNumber[T Number](a T) T { 96 | return a + 1 97 | } 98 | 99 | func main() { 100 | 101 | next := nextNumber(50) 102 | fmt.Println("nextNumber:", next) 103 | 104 | var p Price = 75.50 105 | another := nextNumber(p) 106 | fmt.Println("another nextNumber:", another) 107 | } 108 | 109 | ``` 110 | 111 | You are only allowed to make your custom constraint using the following types. [why?](https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#operations-based-on-type-sets) 112 | 113 | * Ordered is a type constraint that matches any ordered type. 114 | * An ordered type is one that supports the <, <=, >, and >= operators. 115 | 116 | ### Type lists 117 | * ~int | ~int8 | ~int16 | ~int32 | ~int64 | 118 | * ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | 119 | * ~float32 | ~float64 | 120 | * ~string 121 | 122 | ### Generic Types vs Generic Function 123 | So we know that we can write functions that use generic types, but what if we want to create a custom type that can contain generic types? For example, a slice of order-able objects. The new proposal makes this possible. 124 | 125 | ```go 126 | type comparableSlice[T comparable] []T 127 | 128 | func allEqual[T comparable](s comparableSlice[T]) bool { 129 | if len(s) == 0 { 130 | return true 131 | } 132 | last := s[0] 133 | for _, cur := range s[1:] { 134 | if cur != last { 135 | return false 136 | } 137 | last = cur 138 | } 139 | return true 140 | } 141 | 142 | func main() { 143 | fmt.Println(allEqual([]int{4,6,2})) 144 | // false 145 | 146 | fmt.Println(allEqual([]int{1,1,1})) 147 | // true 148 | } 149 | ``` 150 | 151 | 152 | ```go 153 | 154 | func splitAnySlice[T any](s []T) ([]T, []T) { 155 | mid := len(s)/2 156 | return s[:mid], s[mid:] 157 | } 158 | 159 | func main() { 160 | firstInts, secondInts := splitAnySlice([]int{0, 1, 2, 3}) 161 | fmt.Println(firstInts, secondInts) 162 | // prints [0 1] [2 3] 163 | 164 | firstStrings, secondStrings := splitAnySlice([]string{"zero", "one", "two", "three"}) 165 | fmt.Println(firstStrings, secondStrings) 166 | // prints [zero one] [two three] 167 | } 168 | 169 | ``` 170 | 171 | ## Builtin Constraints 172 | * any 173 | * comparable 174 | * Parametric constraints or Custom constraints 175 | 176 | ### Comparable constraint 177 | The comparable constraint is a predefined constraint as well, just like the any constraint. When using the comparable constraint instead of the any constraint, you can use the != and == operators within your function logic. 178 | 179 | ## Generics Golang Playground 180 | * https://gotipplay.golang.org/ 181 | 182 | 183 | ## Why Generics? 184 | * https://go.dev/blog/why-generics 185 | * https://go.dev/blog/survey2020-results 186 | * https://qvault.io/golang/how-to-use-golangs-generics 187 | 188 | ## Resource 189 | * https://go.dev/doc/tutorial/generics 190 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module mateors.com/galaxyshop 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.7.3 // indirect 7 | github.com/go-playground/validator/v10 v10.8.0 // indirect 8 | github.com/golang/protobuf v1.5.2 // indirect 9 | github.com/json-iterator/go v1.1.11 // indirect 10 | github.com/mattn/go-isatty v0.0.13 // indirect 11 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 12 | github.com/modern-go/reflect2 v1.0.1 // indirect 13 | github.com/ugorji/go v1.2.6 // indirect 14 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect 15 | google.golang.org/protobuf v1.27.1 // indirect 16 | gopkg.in/yaml.v2 v2.4.0 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 4 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 5 | github.com/gin-gonic/gin v1.7.3 h1:aMBzLJ/GMEYmv1UWs2FFTcPISLrQH2mRgL9Glz8xows= 6 | github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= 7 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 8 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 9 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 10 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 11 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 12 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 13 | github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k= 14 | github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk= 15 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 16 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 17 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 18 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 19 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 20 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 21 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 22 | github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= 23 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 24 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 25 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 26 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 27 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 28 | github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= 29 | github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 30 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 31 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 32 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 33 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 34 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 35 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 36 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 37 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 38 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 39 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 40 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 41 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 42 | github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= 43 | github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= 44 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 45 | github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= 46 | github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= 47 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 48 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 49 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= 50 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 51 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 52 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 53 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 54 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 55 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 56 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 57 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 58 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 59 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= 60 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 61 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 62 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 63 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 64 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 65 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 66 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 67 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 68 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 69 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 70 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 71 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= 72 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 73 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 74 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 75 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 76 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 77 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 78 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 79 | -------------------------------------------------------------------------------- /golang_find_replace.md: -------------------------------------------------------------------------------- 1 | # Golang find & replace from a file 2 | 3 | 4 | ```golang 5 | 6 | package main 7 | 8 | import ( 9 | "io/ioutil" 10 | "log" 11 | "strings" 12 | ) 13 | 14 | func main() { 15 | input, err := ioutil.ReadFile("myfile") 16 | if err != nil { 17 | log.Fatalln(err) 18 | } 19 | 20 | lines := strings.Split(string(input), "\n") 21 | 22 | for i, line := range lines { 23 | if strings.Contains(line, "]") { 24 | lines[i] = "LOL" 25 | } 26 | } 27 | output := strings.Join(lines, "\n") 28 | err = ioutil.WriteFile("myfile", []byte(output), 0644) 29 | if err != nil { 30 | log.Fatalln(err) 31 | } 32 | } 33 | 34 | ``` 35 | 36 | 37 | ## Reference 38 | * [Stackoverflow](https://stackoverflow.com/questions/26152901/replace-a-line-in-text-file-golang) 39 | * [Another example code](https://gist.github.com/tdegrunt/045f6b3377f3f7ffa408) 40 | -------------------------------------------------------------------------------- /gotracer.md: -------------------------------------------------------------------------------- 1 | # Go Tracer 2 | > an introduction to go tool trace and describing how you can use it to debug concurrent Go programs. 3 | Go makes it easy to use concurrency with goroutines, which means we do more concurrency, which means we have more concurrency problems. 4 | 5 | ## Large File Read challenge 6 | * https://marcellanz.com/post/file-read-challenge/ 7 | 8 | ## How to generate trace.out file? 9 | > copy and paste the following code into your main function 10 | ```golang 11 | func main(){ 12 | //go tool trace 13 | f, err := os.Create("trace.out") 14 | if err != nil { 15 | panic(err) 16 | } 17 | defer f.Close() 18 | 19 | err = trace.Start(f) 20 | if err != nil { 21 | panic(err) 22 | } 23 | defer trace.Stop() 24 | //------------------------ 25 | 26 | //your prgram source code goes here 27 | 28 | } 29 | 30 | ``` 31 | ## run your go program using 32 | > go run main.go 33 | 34 | ## run following code to open trace.out file in your browser 35 | > go tool trace trace.out 36 | 37 | ## Memory allocation debug 38 | > GODEBUG=gctrace=1 go run . 39 | 40 | ## Max processor set 41 | > GOMAXPROCS=3 go run . 42 | 43 | ## Reference 44 | * [Intrdoduction Blog](https://about.sourcegraph.com/go/an-introduction-to-go-tool-trace-rhys-hiltner) 45 | * [Presentation Slide](https://speakerdeck.com/rhysh/an-introduction-to-go-tool-trace?slide=9) 46 | * [Trace tool](https://making.pusher.com/go-tool-trace) 47 | * [Youtube video tutorial](https://www.youtube.com/watch?v=Xq5HDH8y0CE&t=4s) 48 | -------------------------------------------------------------------------------- /groupby.md: -------------------------------------------------------------------------------- 1 | # Group filter code 2 | 3 | ```go 4 | func groupFilteredRows(rows []map[string]interface{}, gFields []string) []map[string]interface{} { 5 | 6 | var rmap = make([]map[string]interface{}, 0) 7 | var guvs = make(map[string][]interface{}) //group wise unique values 8 | 9 | //var sumFields = []string{"Amount"} 10 | var sumkv = make(map[string]float64) 11 | //var total float64 12 | 13 | for _, row := range rows { 14 | 15 | //fmt.Println(i, row) 16 | 17 | for _, grpname := range gFields { 18 | 19 | //fmt.Println(i, j, grpname) 20 | if vals, isExist := guvs[grpname]; !isExist { //new 21 | 22 | var uvals = make([]interface{}, 0) 23 | uvals = append(uvals, row[grpname]) 24 | guvs[grpname] = uvals 25 | //var amounts = make([]interface{}, 0) 26 | //guvs["Amount"] = append(amounts, row["Amount"]) 27 | //fmt.Println(i, j, vals, grpname, row[grpname]) 28 | amountf, _ := strconv.ParseFloat(fmt.Sprintf("%v", row["Amount"]), 64) 29 | sumkv[grpname] = amountf 30 | 31 | } else { //exist 32 | 33 | isFound := FindExist(vals, row[grpname]) 34 | if !isFound { 35 | uvals := append(vals, row[grpname]) 36 | guvs[grpname] = uvals 37 | //fmt.Println(grpname, vals, row[grpname], isFound) 38 | amountf, _ := strconv.ParseFloat(fmt.Sprintf("%v", row["Amount"]), 64) 39 | eamountf := sumkv[grpname] 40 | sumkv[grpname] = eamountf + amountf 41 | } 42 | } 43 | } 44 | //fmt.Println(total) 45 | } 46 | 47 | for key, vals := range guvs { 48 | //fmt.Printf("%v %v %T\n", key, vali, vali) 49 | for _, val := range vals { 50 | kv := make(map[string]interface{}) 51 | // kval, isOk := val.(string) 52 | // if isOk { 53 | // kv[kval] = key 54 | // } 55 | // if !isOk { 56 | // log.Println(val) 57 | // kv[fmt.Sprintf("%v", val)] = key 58 | // } 59 | kv[fmt.Sprintf("%v", val)] = key 60 | //kv["Amount"] = sumkv[key] 61 | rmap = append(rmap, kv) 62 | } 63 | } 64 | // fmt.Println(len(rmap)) 65 | for key, val := range sumkv { 66 | fmt.Println(">>", key, val) 67 | } 68 | return rmap 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /http2.md: -------------------------------------------------------------------------------- 1 | # Golang HTTP2 2 | Go’s standard library HTTP server supports HTTP/2 by default \ 3 | Most users will use it indirectly through the automatic use by the net/http package (from Go 1.6 and later) 4 | 5 | [HTTP2 Demo code](https://github.com/golang/net/blob/master/http2/h2demo/h2demo.go) 6 | 7 | Everything is automatically configured for us, we don’t even need to import Go’s standard library http2 package \ 8 | 9 | HTTP/2 enforces TLS. In order to achieve this we first need a private key and a certificate. On Linux, the following command does the job. Run it and follow the prompted questions. 10 | 11 | ``` 12 | openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt 13 | ``` 14 | The command will generate two files: server.key and server.crt 15 | 16 | * server.key: Contains our server private key 17 | * server.crt: The server certificate - represents the server’s identity and contains the server’s public key 18 | 19 | Now, for the server code, in its simplest form, we will just use Go’s standard library HTTP server and enable TLS with the generated SSL files. 20 | ```golang 21 | package main 22 | 23 | import ( 24 | "log" 25 | "net/http" 26 | ) 27 | 28 | func main() { 29 | // Create a server on port 8000 30 | // Exactly how you would run an HTTP/1.1 server 31 | srv := &http.Server{Addr: ":8000", Handler: http.HandlerFunc(handle)} 32 | 33 | // Start the server with TLS, since we are running HTTP/2 it must be 34 | // run with TLS. 35 | // Exactly how you would run an HTTP/1.1 server with TLS connection. 36 | log.Printf("Serving on https://0.0.0.0:8000") 37 | log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key")) 38 | } 39 | 40 | func handle(w http.ResponseWriter, r *http.Request) { 41 | // Log the request protocol 42 | log.Printf("Got connection: %s", r.Proto) 43 | // Send a message back to the client 44 | w.Write([]byte("Hello")) 45 | } 46 | ``` 47 | 48 | ## Resource 49 | * https://posener.github.io/http2 50 | * https://github.com/posener/h2conn 51 | -------------------------------------------------------------------------------- /interface.md: -------------------------------------------------------------------------------- 1 | # Golang Interface 2 | 3 | ## Hexagonal Architecture 4 | Make sure we devide our software in such a way that each peice of the software maintain its separation of concerns 5 | by doing this make it extreamly modular. 6 | 7 | 1. App and domain logic in the middle 8 | 2. Ports & Adapters 9 | 3. User interface 10 | 4. Repo 11 | 5. External API 12 | 6. Message Queue 13 | 7. REST | GraphQL 14 | 15 | ## Decoupling 16 | 17 | ```go 18 | package main 19 | 20 | import ( 21 | "fmt" 22 | ) 23 | 24 | type reader interface { 25 | read() (int, error) 26 | } 27 | 28 | type file struct { 29 | name string 30 | fileContent string 31 | } 32 | 33 | func (f *file) read() (int, error) 34 | content := "file contents" 35 | f.fileContent = content 36 | return len(content), nil 37 | } 38 | 39 | type pipe struct { 40 | name string 41 | pipeMessage string 42 | } 43 | 44 | func (p *pipe) read() (int, error) { 45 | msg := `{name: "Henry", title: "developer"}` 46 | p.pipeMessage = msg 47 | return len(msg), nil 48 | } 49 | 50 | func main() { 51 | f := file{ 52 | name: "data.json", 53 | } 54 | p := pipe{ 55 | name: "pipe_message", 56 | } 57 | 58 | retrieve(&f) 59 | fmt.Println(f.fileContent) 60 | retrieve(&p) 61 | fmt.Println(p.pipeMessage) 62 | } 63 | 64 | func retrieve(r reader) error { 65 | len, _ := r.read() 66 | fmt.Println(fmt.Sprintf("read %d bytes", len)) 67 | return nil 68 | } 69 | ``` 70 | 71 | 72 | ### Package used in this project 73 | * github.com/teris-io/shortid 74 | * github.com/vmihailenco/msgpack 75 | * gopkg.in/dealancer/validate.v2 76 | 77 | ## Resource 78 | * [Interface](https://www.youtube.com/watch?v=qJKQZKGZgf0) 79 | * [Hexagonal Microservices with Go](https://www.youtube.com/watch?v=rQnTtQZGpg8) 80 | * [MessagePack](https://msgpack.org/index.html) 81 | * [Golang Tensor Programming](https://www.youtube.com/watch?v=QyBXz9SpPqE&list=PLJbE2Yu2zumCe9cO3SIyragJ8pLmVv0z9) 82 | * [understand-go-golang-interfaces](https://duncanleung.com/understand-go-golang-interfaces) 83 | -------------------------------------------------------------------------------- /ip.md: -------------------------------------------------------------------------------- 1 | # Get All ip in the world 2 | 3 | https://whois.ipip.net/AS58890 4 | 5 | 6 | # Reference 7 | * https://septs.blog/projects/ 8 | -------------------------------------------------------------------------------- /jwt.md: -------------------------------------------------------------------------------- 1 | # JWT Token 2 | 3 | ```go 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | 10 | "github.com/golang-jwt/jwt" 11 | ) 12 | 13 | func main() { 14 | 15 | var email, role string = "billahmdmostain@gmail.com", "Admin" 16 | token, err := GenerateJWT(email, role) 17 | fmt.Println(token, err) 18 | 19 | ValidateJWT(token) 20 | 21 | } 22 | 23 | func GenerateJWT(email, role string) (string, error) { 24 | 25 | secretkey := "121212" 26 | var mySigningKey = []byte(secretkey) 27 | token := jwt.New(jwt.SigningMethodHS256) 28 | claims := token.Claims.(jwt.MapClaims) 29 | 30 | claims["authorized"] = true 31 | claims["email"] = email 32 | claims["role"] = role 33 | claims["exp"] = time.Now().Add(time.Minute * 30).Unix() 34 | 35 | tokenString, err := token.SignedString(mySigningKey) 36 | 37 | if err != nil { 38 | err = fmt.Errorf("Something Went Wrong: %s", err.Error()) 39 | return "", err 40 | } 41 | return tokenString, nil 42 | } 43 | 44 | func ValidateJWT(tokenString string) { 45 | 46 | //jwt.ParseWithClaims() 47 | secretkey := "121212" 48 | var mySigningKey = []byte(secretkey) 49 | 50 | token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { 51 | if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { 52 | return nil, fmt.Errorf("There was an error in parsing") 53 | } 54 | return mySigningKey, nil 55 | }) 56 | 57 | fmt.Println(token, err) 58 | fmt.Println(token.Valid) 59 | claims, ok := token.Claims.(jwt.MapClaims) 60 | fmt.Println(claims, ok) 61 | 62 | } 63 | ``` 64 | 65 | ## Learning Resource 66 | * [Securing Your Go REST APIs with JSON Web Tokens](https://www.youtube.com/watch?v=-Scg9INymBs) 67 | -------------------------------------------------------------------------------- /load.md: -------------------------------------------------------------------------------- 1 | ## Golang http load test 2 | 3 | https://github.com/rakyll/hey 4 | 5 | ## gops is a command to list and diagnose Go processes currently running on your system. 6 | > It is possible to use gops tool both in local and remote mode. 7 | * https://github.com/google/gops 8 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | _ "embed" 6 | "fmt" 7 | "net/http" 8 | "path" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | var router *gin.Engine 14 | 15 | //go:embed assets/* 16 | var staticFS embed.FS 17 | 18 | func init() { 19 | router = gin.Default() 20 | 21 | // de, err := tem.ReadDir("assets") 22 | // fmt.Println(">>", err) 23 | // for k, v := range de { 24 | 25 | // fs, _ := v.Info() 26 | // fmt.Println(k, v.Name(), fs.Name(), fs.Size()) 27 | // } 28 | //gin.SetMode(gin.ReleaseMode) // 29 | 30 | //fmt.Println(path.Join("/assets/", "/resources")) 31 | 32 | } 33 | 34 | func main() { 35 | 36 | //gin.HandlerFunc 37 | router.LoadHTMLGlob("template/*") 38 | 39 | //http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(tem)))) 40 | //fs := http.FileServer(tem) 41 | //router.StaticFS("/resources", http.FS(tem)) 42 | 43 | router.GET("/:foldername/*filepath", func(c *gin.Context) { 44 | 45 | fmt.Println("folder:", c.Param("foldername")) 46 | 47 | for key, val := range c.Params { 48 | fmt.Println(key, "==", val) 49 | } 50 | 51 | c.FileFromFS(path.Join("/assets/", c.Request.URL.Path), http.FS(staticFS)) 52 | }) 53 | 54 | router.GET("/", func(c *gin.Context) { 55 | 56 | c.HTML(http.StatusOK, "index.gohtml", gin.H{"title": "Hello world"}) 57 | 58 | }) 59 | 60 | router.GET("/about", Aboutpage) 61 | 62 | router.Run(":8080") 63 | 64 | } 65 | 66 | func Aboutpage(c *gin.Context) { 67 | 68 | data := struct { 69 | Title string 70 | Page string 71 | }{ 72 | 73 | Title: "About us", 74 | Page: "About", 75 | } 76 | c.HTML(http.StatusOK, "about.gohtml", data) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /messagebroker.md: -------------------------------------------------------------------------------- 1 | # Message Broker 2 | 3 | * https://centrifugal.dev/ 4 | * https://github.com/nsqio/nsq 5 | * https://github.com/rylans/getlang 6 | * https://github.com/abadojack/whatlanggo 7 | * https://github.com/james-bowman/nlp 8 | * https://go.dev/security/vuln/ 9 | * https://github.com/minio/minio 10 | * https://github.com/huandu/facebook 11 | * https://github.com/google/go-github 12 | * https://github.com/shurcooL/githubv4 13 | * https://github.com/sashabaranov/go-openai 14 | * https://github.com/dghubble/go-twitter 15 | * https://github.com/avelino/awesome-go 16 | -------------------------------------------------------------------------------- /multipart.md: -------------------------------------------------------------------------------- 1 | 2 | ## Tutorial 3 | * https://freshman.tech/file-upload-golang/ 4 | * https://ayada.dev/posts/multipart-requests-in-go/ 5 | * https://www.mohitkhare.com/blog/file-upload-golang/ 6 | 7 | 8 | ## Resources 9 | * [AWS S3 Multipart Upload in Golang](https://www.youtube.com/watch?v=fEVRl9MLJC0) 10 | -------------------------------------------------------------------------------- /mutex.md: -------------------------------------------------------------------------------- 1 | ## Mutex -> sync.Mutex 2 | Mutex is short for mutual exclusion. Mutexes keep track of which thread has access to a variable at any given time. 3 | ![Mutex](https://res.cloudinary.com/practicaldev/image/fetch/s---IMLhEFN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/qvault.io/wp-content/uploads/2020/03/download.png%3Fw%3D742%26ssl%3D1) 4 | 5 | ## Read & Write Lock 6 | * Read lock: multiple concurrent read operations can be performed at the same time, and write operations are not allowed 7 | * Write lock: only one coroutine is allowed to write at the same time, and other write and read operations are not allowed 8 | 9 | * Read only mode: multi process can be read but not written 10 | * Write only mode: single co process can be written but not readable 11 | 12 | ```go 13 | wg := &sync.WaitGroup{} 14 | mut := &sync.Mutex{} 15 | 16 | var result []float64 //shared resource 17 | 18 | wg.Add(1) 19 | go func() { 20 | mut.Lock() 21 | fmt.Println("worker 1") 22 | result = append(result, 50.50) 23 | mut.Unlock() 24 | wg.Done() 25 | }() 26 | 27 | wg.Add(1) 28 | go func() { 29 | mut.Lock() 30 | fmt.Println("worker 2") 31 | result = append(result, 78.50) 32 | mut.Unlock() 33 | wg.Done() 34 | }() 35 | 36 | wg.Wait() 37 | fmt.Println(result) 38 | ``` 39 | 40 | 41 | ## Semaphore 42 | The semaphore is the concept that allows In-N-Out to receive 4 orders in a restaurent concurrently (actually in parallel), causing everyone else to sit and wait. 43 | 44 | ### Let's compare a mutex to a sempahore 45 | * If a mutex is concerned with ensuring a single thread ever accesses code exclusively 46 | * a semaphore is concerned with ensuring at most N threads can ever access code exclusively. 47 | 48 | > a semaphore is a more generalized version of a mutex 49 | 50 | ### What's the point of giving exclusive access to N threads? 51 | The point is that in this scenario you are purposefully constraining access to a resource therefore protecting that resource from overuse. 52 | 53 | > **mutex**: constrains access to a 1 single thread, to guard a critical section of code. 54 | 55 | > **semaphore**: constrains access to at most N threads, to control/limit concurrent access to a shared resource 56 | 57 | ```go 58 | 59 | type Post struct { 60 | UserID int64 `json:"userId"` 61 | ID int64 `json:"id"` 62 | Title string `json:"title"` 63 | Body string `json:"body"` 64 | } 65 | 66 | func semaphoreExample() { 67 | 68 | var p Post 69 | wg := &sync.WaitGroup{} 70 | wg.Add(100) 71 | 72 | //sem := make(chan bool, 10) 73 | sem := make(chan struct{}, 10) 74 | mut := &sync.Mutex{} //overcome race condition 75 | 76 | for i := 1; i <= 100; i++ { 77 | 78 | fmt.Println(runtime.NumGoroutine()) 79 | //sem <- true 80 | sem <- struct{}{} //an array of empty structs, which occupies no storage. 81 | 82 | go func(i int) { 83 | 84 | defer wg.Done() 85 | defer func() { <-sem }() 86 | 87 | res, err := http.Get(fmt.Sprintf("https://jsonplaceholder.typicode.com/posts/%d", i)) 88 | if err != nil { 89 | log.Fatal(err) 90 | } 91 | 92 | mut.Lock() 93 | err = json.NewDecoder(res.Body).Decode(&p) //race 94 | if err != nil { 95 | //return err 96 | log.Fatal(err) 97 | } 98 | fmt.Println(p.ID, p.Title) 99 | mut.Unlock() 100 | 101 | }(i) 102 | 103 | } 104 | 105 | wg.Wait() 106 | } 107 | ``` 108 | 109 | > GODEBUG=gctrace=1 go run main.go 110 | 111 | > time go run --race main.go 112 | 113 | ### When using a semaphore how do you figure out the value of N for how many threads to limit? 114 | Unfortunately there is no hard and fast rule and the final number of N is going to depend on many factors. A good place to start is by benchmarking and actually hitting your shared resource to see where it starts to fall over in terms of performance and latency. 115 | 116 | ## Resource 117 | * [Mutex Fundamentals](https://www.sohamkamani.com/golang/mutex) 118 | * [rwMutex](https://dev.to/qvault/golang-mutexes-what-is-rwmutex-for-57a0) 119 | * [Read-Write Code Analysis](https://www.mo4tech.com/golang-series-rwmutex-read-write-lock-analysis.html) 120 | * [sync.Mutex Video Explanation](https://www.youtube.com/watch?v=JlmYLPxwVzQ) 121 | * [Mutex vs Synchronization](https://www.youtube.com/watch?v=jkRN9zcLH1s) 122 | * [Semaphore and Mutex](https://www.youtube.com/watch?v=DvF3AsTglUU) 123 | * [concurrency-semaphores](https://medium.com/@deckarep/gos-extended-concurrency-semaphores-part-1-5eeabfa351ce) 124 | -------------------------------------------------------------------------------- /os.md: -------------------------------------------------------------------------------- 1 | # OS File structure 2 | > syscall and getdents function 3 | 4 | * https://forum.golangbridge.org/t/help-with-syscall-and-getdents-function/23855/2 5 | 6 | ## Standard pipe 7 | * https://github.com/skillian/standpipe/blob/d4cc79e8ed09a1e965ab721c9bad83427dc25aed/v1pipe.go 8 | -------------------------------------------------------------------------------- /pool.md: -------------------------------------------------------------------------------- 1 | ## Custom Pool implementation using golang 2 | 3 | ```golang 4 | package cpool 5 | 6 | type MyModel struct{ 7 | Name string 8 | Salary float64 9 | Age int 10 | } 11 | 12 | //you may increase accodring to your project need 13 | const POOL_SIZE = 1000 14 | 15 | //Global pool variable | resource pool 16 | var pool chan *MyModel 17 | 18 | func init() { 19 | pool = make(chan *MyModel, POOL_SIZE) 20 | } 21 | 22 | //Add/Allocate resource to the pool or pick from the existing pool 23 | // Get() 24 | func Get() *MyModel { 25 | select { 26 | case cr := <-pool: 27 | return cr 28 | default: 29 | cr := &MyModel{} 30 | return cr 31 | } 32 | } 33 | 34 | //Release resource from the pool 35 | //Garbage Collector (GC) is relaxed now 36 | //Put() | put resource back 37 | func Put(cr *MyModel) { 38 | select { 39 | case pool <- cr: 40 | default: 41 | } 42 | } 43 | 44 | ``` 45 | 46 | ## Implementation 47 | ```golang 48 | 49 | //import "sync/atomic" 50 | //import "encoding/json" 51 | //import "time" 52 | //import "net/http" 53 | 54 | type Data struct { 55 | numReqs uint64 56 | name string 57 | value log.Logger 58 | } 59 | 60 | func (d *Data) Add(){ 61 | 62 | //Any business login implementation 63 | // Your code 64 | } 65 | 66 | func (d *Data) ServeHTTP(w http.ResponseWriter, r *http.Request) { 67 | 68 | atomic.AddUint64(&d.numReqs, 1) 69 | 70 | go func(){ 71 | 72 | dec := json.NewDecoder(r.Body) 73 | defer r.Body.Close() 74 | 75 | myModel := cp.Get() 76 | dec.Decode(myModel) 77 | // INFO - pretent we do some work on with the msg 78 | time.Sleep(10 * time.Millisecond) 79 | co.Put(myModel) 80 | }() 81 | 82 | } 83 | ``` 84 | 85 | ## Resource 86 | * [Go Concurrency Worker Pool Pattern like I’m five](https://itnext.io/explain-to-me-go-concurrency-worker-pool-pattern-like-im-five-e5f1be71e2b0) 87 | * [Golang package](https://github.com/mateors/pond) 88 | * [Worker pool video tutorial](https://www.youtube.com/watch?v=1iBj5qVyfQA) 89 | * [Implemention Resource Pool Part-1](https://www.youtube.com/watch?v=G33OlABzxW8) 90 | * [Part-2](https://www.youtube.com/watch?v=HNZTJZ7Buk0) 91 | * [Part-3](https://www.youtube.com/watch?v=h6ZwhM20_Yo) 92 | * [Resouce-pool code](https://github.com/striversity/gotr/tree/master/021-resouce-pool) 93 | * [Detailed-explanation](https://developpaper.com/detailed-explanation-of-the-use-of-sync-pool-in-golang/) 94 | * [Handling-1-million-requests-per-minute](http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/) 95 | * [Mysql 1 billion record processing](https://github.com/rcbensley/brimming) 96 | * [Sqlite data generator](https://github.com/sqlitebrowser/sqlitedatagen) 97 | * [multithreading-to-read-large-files](https://hackernoon.com/leveraging-multithreading-to-read-large-files-faster-in-go-lmn32t7) 98 | * [Build a TCP Connection Pool From Scratch](https://betterprogramming.pub/build-a-tcp-connection-pool-from-scratch-with-go-d7747023fe14?gi=b3978a42d21d) 99 | * [Simple code](https://chowdera.com/2021/07/20210715165328495l.html) 100 | * [how-to-make-1-million-get-request](https://forum.golangbridge.org/t/how-to-make-1-million-get-request-with-golang-concurrency-in-low-end-windows-pc/16628) 101 | -------------------------------------------------------------------------------- /race.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ```go 4 | package main 5 | 6 | import "fmt" 7 | 8 | func main() { 9 | 10 | //most repeated character 11 | //fmt.Println(90 - 65) //A-Z 12 | //fmt.Println(122 - 97) //a-z 13 | 14 | input := "aAbcacdddaa" 15 | 16 | var char rune 17 | var freq int 18 | 19 | amap := make(map[rune]int) 20 | 21 | for _, c := range input { 22 | 23 | //fmt.Println(i, c) 24 | if c >= 97 && c <= 122 { 25 | fmt.Println("small:", c, string(c)) 26 | 27 | if res, isOk := amap[c]; isOk { 28 | amap[c] = res + 1 29 | } else { 30 | amap[c] = 1 31 | } 32 | } 33 | if c >= 65 && c <= 90 { 34 | fmt.Println("CAPITAL:", c, string(c)) 35 | if res, isOk := amap[c]; isOk { 36 | amap[c] = res + 1 37 | } else { 38 | amap[c] = 1 39 | } 40 | } 41 | 42 | count := amap[c] 43 | if count > freq { 44 | freq = count 45 | char = c 46 | } 47 | 48 | } 49 | 50 | fmt.Println(amap, char) 51 | 52 | } 53 | 54 | ``` 55 | ## Race condition 56 | 57 | A race condition in Go occurs when two or more goroutines have shared data and interact with it simultaneously. 58 | 59 | Run the following code to see the output 60 | > go run --race main.go 61 | 62 | ```go 63 | 64 | package main 65 | 66 | import ( 67 | "fmt" 68 | "sync" 69 | ) 70 | 71 | func main() { 72 | 73 | wg := sync.WaitGroup{} 74 | var result []float64 75 | 76 | wg.Add(1) 77 | go func() { 78 | fmt.Println("worker 1") 79 | result = append(result, 50.50) 80 | wg.Done() 81 | }() 82 | 83 | wg.Add(1) 84 | go func() { 85 | fmt.Println("worker 2") 86 | result = append(result, 78.50) 87 | wg.Done() 88 | }() 89 | 90 | wg.Wait() 91 | fmt.Println(result) 92 | } 93 | ``` 94 | 95 | ## Overcome race condition using sync.Mutex Package 96 | The sync.Mutex package provides a mechanism to guard a block of code, making it concurrency-safe, meaning write operations within that block will be safe. 97 | 98 | ```go 99 | wg := &sync.WaitGroup{} 100 | mut := &sync.Mutex{} 101 | var result []float64 102 | 103 | wg.Add(1) 104 | go func() { 105 | mut.Lock() 106 | fmt.Println("worker 1") 107 | result = append(result, 50.50) 108 | mut.Unlock() 109 | wg.Done() 110 | }() 111 | 112 | wg.Add(1) 113 | go func() { 114 | mut.Lock() 115 | fmt.Println("worker 2") 116 | result = append(result, 78.50) 117 | mut.Unlock() 118 | wg.Done() 119 | }() 120 | 121 | wg.Wait() 122 | fmt.Println(result) 123 | ``` 124 | ### Windows PowerShell race test 125 | > `$Env:CGO_ENABLED=1;$Env:GOOS="windows"; go run --race .` 126 | -------------------------------------------------------------------------------- /recursive.md: -------------------------------------------------------------------------------- 1 | ## Recursive function 2 | Best real world recurive function example \ 3 | Find Excel column name from a given column number. 4 | 5 | ```go 6 | func colid(num int) string { 7 | 8 | var alphabets string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 9 | if num <= 0 { 10 | return "" 11 | } 12 | if num < 26 { 13 | return fmt.Sprintf(`%c`, alphabets[num-1]) 14 | } 15 | rem := num % 26 //remainder 16 | fld := num / 26 //floor-division 17 | if rem == 0 { 18 | rem = 26 19 | if fld == 1 { 20 | return fmt.Sprintf(`%c`, alphabets[rem-1]) 21 | } 22 | return fmt.Sprintf(`%s%c`, colid(fld-1), alphabets[rem-1]) 23 | } 24 | return fmt.Sprintf(`%s%c`, colid(fld), alphabets[rem-1]) 25 | } 26 | ``` 27 | ### usage: 28 | > fmt.Println(colid(1)) //A \ 29 | > fmt.Println(colid(26)) //Z \ 30 | > fmt.Println(colid(27)) //AA \ 31 | > fmt.Println(colid(52)) //AZ \ 32 | > fmt.Println(colid(705)) //AAC 33 | -------------------------------------------------------------------------------- /reflect.md: -------------------------------------------------------------------------------- 1 | # Reflect 2 | 3 | ## String variable 4 | ```go 5 | name := "mostain" 6 | rv := reflect.ValueOf(name) 7 | fmt.Println("string:", rv.String()) 8 | fmt.Println("kind:", rv.Kind()) 9 | fmt.Println("type:", rv.Type()) 10 | fmt.Println("length:", rv.Len()) 11 | ``` 12 | 13 | ## Array variable 14 | ```go 15 | stds := []string{"Istiyak", "Hasan", "Dipu"} 16 | fmt.Println("kind:", reflect.ValueOf(stds).Kind()) //slice 17 | fmt.Println("type:", reflect.ValueOf(stds).Type()) 18 | fmt.Println("length:", reflect.ValueOf(stds).Len()) 19 | len := reflect.ValueOf(stds).Len() 20 | for i := 0; i < len; i++ { 21 | fmt.Println(i, "->", reflect.ValueOf(stds).Index(i)) 22 | } 23 | ``` 24 | 25 | ## Func 26 | ```go 27 | greet := func(s, t, u string) string { return fmt.Sprintf("%s %s %s", s, t, u) } 28 | frv := reflect.ValueOf(greet) 29 | fmt.Println("string:", frv.String()) 30 | fmt.Println("kind:", frv.Kind()) 31 | fmt.Println("type:", frv.Type()) 32 | fmt.Println("parameter count:", frv.Type().NumIn()) 33 | ``` 34 | 35 | ## Struct 36 | ```go 37 | func Details(inf interface{}) []string { 38 | 39 | var fields []string 40 | typof := reflect.TypeOf(inf) 41 | count := typof.NumField() 42 | for i := 0; i < count; i++ { 43 | third := typof.Field(i).Name 44 | fields = append(fields, third) 45 | } 46 | return fields 47 | } 48 | 49 | //call 50 | var p Person 51 | fmt.Println(Details(p)) //[Name Age Height Gender] 52 | 53 | ``` 54 | 55 | ## Map 56 | ```go 57 | row := make(map[string]interface{}) 58 | row["name"] = "Arisha" 59 | row["age"] = 6 60 | row["height"] = 4.2 61 | 62 | trow := reflect.TypeOf(row) 63 | fmt.Println("string:", trow.String()) 64 | fmt.Println("kind:", trow.Kind()) 65 | fmt.Println("keyType:", trow.Key()) //key type 66 | fmt.Println("valueType:", trow.Elem()) //value type 67 | //melm := trow.Elem() 68 | 69 | fmt.Println("--------------------") 70 | 71 | vrow := reflect.ValueOf(row) 72 | fmt.Println("string:", vrow.String()) 73 | fmt.Println("type:", vrow.Type()) 74 | fmt.Println("kind:", vrow.Kind()) 75 | fmt.Println("keys:", vrow.MapKeys()) 76 | 77 | 78 | for key, val := range vrow.MapKeys() { 79 | fmt.Println(">>", key, val) 80 | } 81 | 82 | iter := vrow.MapRange() 83 | for iter.Next() { 84 | k := iter.Key() 85 | v := iter.Value() 86 | fmt.Println(k, v) 87 | } 88 | ``` 89 | -------------------------------------------------------------------------------- /router.md: -------------------------------------------------------------------------------- 1 | # Build your own Custom Router 2 | * [golang-http-router](https://dev.to/bmf_san/introduction-to-golang-http-router-made-with-nethttp-3nmb) 3 | * [My favorite lightweight router](https://go-chi.io/#/README) 4 | -------------------------------------------------------------------------------- /smpp.md: -------------------------------------------------------------------------------- 1 | # SMPP Protocol 2 | 3 | nc -z -v -u 10.10.8.8 20-80 2>&1 | grep succeeded 4 | 5 | sudo nmap -sU -p- 10.10.8.8 6 | 7 | https://linuxize.com/post/check-open-ports-linux/ 8 | 9 | SMPP is an asynchronous protocol. This means that an ESME or MC can send several 10 | requests at a time to the other party. 11 | 12 | SMPP operations are based on the exchange of operation PDUs between ESME and MC 13 | 14 | Most SMPP sessions will be ESME-initiated, but as we have seen from Outbind, the MC can 15 | itself be in a position to connect to an ESME that is configured for Outbind. 16 | 17 | 18 | first establishing a secure and authenticated connection before commencing the 19 | SMPP session. 20 | 21 | 22 | ## interface_version to be set to 0x50 23 | 24 | Type Length Values (TLV) represent individual pieces of data that make up the ADS message conten 25 | 26 | Values depicted with a 0x prefix are in Hexidecimal format, meaning that each digit 27 | represents 4 binary bits. Thus, a 2-digit hex number is represented by 1 octet of data. 28 | 29 | The octets are always encoded in Most Significant 30 | Byte (MSB) first order, otherwise known as Big Endian 31 | Encoding. 32 | 33 | ![MSB_LSB](https://www.learnpick.in/userfiles/resources_conversion_files/presentation_digital_systems_introduction_1448524485_68825-10.jpg) 34 | 35 | References to a NULL setting for a field imply that the field is not carrying a value. However 36 | the NULL octet must still be encoded in the PDU. 37 | 38 | The 16-0ctet SMPP Header is a mandatory part of every SMPP PDU and must always be 39 | present. The SMPP PDU Body is optional and may not be included with every SMPP PDU. 40 | There are two ways of viewing a PDU; either as a 16-octet header plus (command_length – 41 | 16) octets for the body or as a 4-octet command_length plus (command_length – 4) octets 42 | for the remaining PDU data. 43 | 44 | > SMPP is a binary protocol and also supports asynchronous transmission 45 | 46 | 47 | ## The Operations are described in 6 categories: 48 | * Session Management 49 | * Message Submission 50 | * Message Delivery 51 | * Message Broadcast 52 | * Anciliary Submission 53 | * Anciliary Broadcast. 54 | 55 | > Bind Operation = MC login request 56 | 57 | ## SMPP Client Simulation 58 | * https://melroselabs.com/tools/smppclient/ 59 | * 60 | 61 | ## Reference 62 | * [SMPP Version 5 Docs](https://smpp.org/SMPP_v5.pdf) 63 | * [SMPP Version 3.4 Docs](https://smpp.org/SMPP_v3_4_Issue1_2.pdf) 64 | * [SMS Forum](https://smsforum.net) 65 | * [Other Provider Features](https://melroselabs.com/docs/reference/smpp/smpp-v5) 66 | * [Third Party Docs](http://www.smscentral.com.au/wp-content/uploads/SMS-Central-SMPP-Implementation-Guide-March-2017.pdf) 67 | * [RICH Messaging](https://melroselabs.com/services/rich-messaging/) 68 | * [DTLS](https://github.com/pion/dtls) 69 | * [STunnel](https://www.stunnel.org/vulns.html) 70 | -------------------------------------------------------------------------------- /smpp_27-09-2021: -------------------------------------------------------------------------------- 1 | To avoid race conditions 2 | 3 | https://www.developer.com/languages/understanding-structs-in-go/ 4 | 5 | https://stackoverflow.com/questions/52533312/what-is-the-best-way-to-hide-struct-fields-and-yet-make-it-synchronise-access-an 6 | 7 | git config --list 8 | 9 | /home/mostain/Downloads 10 | 11 | sudo rm -rf /usr/local/go && tar -C /usr/local -xzf /home/mostain/Downloads/go1.17.1.linux-amd64.tar.gz 12 | 13 | sudo tar -C /usr/local -xzf /home/mostain/Downloads/go1.17.1.linux-amd64.tar.gz 14 | 15 | git config --global user.email 16 | 17 | git merge --ff-only main 18 | 19 | 20 | --allow-unrelated-histories 21 | 22 | git merge origin/main --allow-unrelated-histories 23 | 24 | 25 | could not import github.com/mateors/mfile ( 26 | 27 | cannot find package "github.com/mateors/mfile" in any of 28 | 29 | /usr/local/go/src/github.com/mateors/mfile (from $GOROOT) 30 | /home/mostain/go/src/github.com/mateors/mfile 31 | 32 | (from 33 | 34 | /usr/local/go 35 | 36 | /home/mostain/go/src/github.com/mateors/mfile 37 | /home/mostain/go/src/github.com/mateors/mfile 38 | 39 | /home/mostain/go/src/mastrhost/main.go 40 | 41 | https://www.portaone.com/ 42 | As per our Conversation, we have created new account which only for access you! 43 | Please find only Billing login info not after login check SMPP credential , 44 | 45 | SMS Portal : https://smpp.irak.com.bd 46 | User : msbillah 47 | Password : msbillah 48 | SMS IP : 72.21.25.134 / or smpp.irak.com.bd 49 | 72.21.25.134 50 | 51 | 35.207.253.140 52 | 53 | SMPP Port : 12220 54 | HTTP Port : 12250 Server: Jetty(9.4.25.v20191220) 55 | HTTPS Port : 12260 Connection refused 56 | 57 | apiKey: a7dbb731492375d9 58 | SecretKey: 68a43d25 59 | 60 | http://192.168.18.119:8585/sendtext?apikey=a7dbb731492375d9&secretkey=68a43d25&callerI 61 | D=8801847&toUser=8801768760886&messageContent=Master-Academy 62 | 63 | 64 | http://192.168.18.119:8585/sendtext?apikey=5d2a&secretkey=465&callerI 65 | D=8801847&toUser=452621&messageContent=abcd&hash=asdfsadds 66 | 67 | https://smpp.org/#smppoverview 68 | https://smpp.org/SMPP_v3_4_Issue1_2.pdf 69 | 70 | 71 | The Short Message Peer to Peer (SMPP) protocol is an open, industry standard protocol 72 | designed to provide a flexible data communications interface for transfer of short message data 73 | between a Message Center, such as a Short Message Service Centre (SMSC), GSM 74 | Unstructured Supplementary Services Data (USSD) Server or other type of Message Center 75 | and a SMS application system, such as a WAP Proxy Server, EMail Gateway or other 76 | 77 | Messaging Gateway. 78 | Note: For sake of brevity, the term SMSC will be used throughout this document to describe 79 | any SMPP ‘server’ entity to which an SMPP ‘client’, termed an External Short 80 | Message Entity (ESME), can be connected 81 | 82 | 83 | Using the SMPP protocol, an SMS application system called the ‘External Short Message 84 | Entity’ (ESME) may initiate an application layer connection with an SMSC over a TCP/IP or 85 | X.25 network connection and may then send short messages and receive short messages to and 86 | from the SMSC respectively. The ESME may also query, cancel or replace short messages 87 | using SMPP. 88 | 89 | 90 | 91 | 92 | SMPP supports a full featured set of two-way messaging functions such as:- 93 | • Transmit messages from an ESME to single or multiple destinations via the SMSC 94 | • An ESME may receive messages via the SMSC from other SME’s (e.g. mobile 95 | stations). 96 | • Query the status of a short message stored on the SMSC 97 | • Cancel or replace a short message stored on the SMSC 98 | • Send a registered short message (for which a ‘delivery receipt’ will be returned by the 99 | SMSC to the message originator) 100 | • Schedule the message delivery date and time 101 | • Select the message mode, i.e. datagram or store and forward 102 | • Set the delivery priority of the short message 103 | • Define the data coding type of the short message 104 | • Set the short message validity period 105 | • Associate a service type with each message e.g. voice mail notification 106 | 107 | 108 | This document defines Version 3.4 of the SMPP protocol and specifies the command and 109 | response format to be used when implementing an SMPP v3.4 protocol interface. 110 | 111 | 112 | 113 | The SMPP protocol defines: 114 | • a set of operations for the exchange of short messages between an ESME and an SMSC 115 | • the data that an ESME application must exchange with an SMSC during SMPP operations. 116 | 117 | 118 | 119 | 120 | SMPP is based on the exchange of request and response protocol data units (PDUs) between 121 | the ESME and the SMSC over an underlying TCP/IP or X.25 network connection. The SMPP 122 | protocol defines: 123 | 124 | • a set of operations and associated Protocol Data Units (PDUs) for the exchange of short 125 | messages between an ESME and an SMSC 126 | • the data that an ESME application can exchange with an SMSC during SMPP operations. 127 | 128 | 129 | 130 | Every SMPP operation must consist of a request PDU and associated response PDU. 131 | The receiving entity must return the associated SMPP response to an SMPP PDU 132 | request. 133 | 134 | 135 | The only exception to this rule is 136 | - the alert_notification PDU for which there is no response 137 | 138 | 139 | opaque value: 140 | this means a value which reveals no details other then the type of the value itself. 141 | 142 | 143 | https://pkg.go.dev/golang.org/x/exp/shiny/screen 144 | 145 | https://memorylapse.ca/post/pixel-monitor/ 146 | 147 | 148 | https://github.com/faiface/pixel/ 149 | 150 | https://github.com/go-gl/glfw/ 151 | 152 | This write up explores how to access video device drivers using the Video for Linux API (or V4L2) and the Go standard libraries, with no Cgo, to build realtime video capture and streaming programs. 153 | 154 | video capture 155 | 156 | devName := "/dev/video0" 157 | 158 | https://github.com/marethyu/gotube/blob/master/gotube.go 159 | 160 | https://www.youtube.com/get_video_info?&video_id= 161 | https://www.youtube.com/get_video_info?&video_id= 162 | 163 | https://github.com/hybridgroup/mjpeg/blob/master/stream.go 164 | 165 | https://stackoverflow.com/questions/63535380/how-to-stream-video-capture-to-web 166 | 167 | https://nametbd.slugsy.me/record-video-using-golang-and-your-webcam-without-opencv-cgo-minggw-692d1126315f 168 | 169 | https://github.com/vee2xx/camtron/blob/master/webcam.go 170 | 171 | https://github.com/faiface/pixel/ 172 | 173 | https://medium.com/learning-the-go-programming-language/realtime-video-capture-with-go-65a8ac3a57da 174 | 175 | https://github.com/vladimirvivien/go4vl/blob/main/v4l2/device.go 176 | 177 | https://memorylapse.ca/post/pixel-monitor/ 178 | 179 | https://memorylapse.ca/post/pixel-monitor/ 180 | 181 | https://smpp.org/SMPP_v3_4_Issue1_2.pdf 182 | 183 | https://github.com/CodeMonkeyKevin/smpp34 184 | 185 | https://github.com/linxGnu/gosmpp 186 | 187 | https://github.com/linxGnu/gosmpp/blob/master/example/main.go 188 | 189 | https://melroselabs.com/services/smsc-simulator/ 190 | 191 | Server: smscsim.melroselabs.com 192 | Port: 2775 (non-TLS), 8775 (TLS) 193 | System ID: 340485 194 | Password: f9d2f3 (valid 10-days) 195 | -------------------------------------------------------------------------------- /students.txt: -------------------------------------------------------------------------------- 1 | Anonnya 2 | Tareq 3 | Asgor -------------------------------------------------------------------------------- /tcp.md: -------------------------------------------------------------------------------- 1 | 2 | ## TCP Server 3 | ```go 4 | package main 5 | 6 | import ( 7 | "bufio" 8 | "io" 9 | "net" 10 | "os/exec" 11 | ) 12 | 13 | func main() { 14 | l, _ := net.Listen("tcp", "127.0.0.1:8080") 15 | for { 16 | c, _ := l.Accept() 17 | go func() { 18 | handle(&c) 19 | }() 20 | } 21 | 22 | } 23 | 24 | func handle(c *net.Conn) { 25 | cmd := exec.Command("top", "-b") 26 | cstdout, _ := cmd.StdoutPipe() 27 | go io.Copy(bufio.NewWriter(*c), bufio.NewReader(cstdout)) 28 | cmd.Run() 29 | } 30 | ``` 31 | 32 | ## TCP Client 33 | ```go 34 | package main 35 | 36 | import ( 37 | "fmt" 38 | "io" 39 | "net" 40 | ) 41 | 42 | func main() { 43 | conn, err := net.Dial("tcp", "127.0.0.1:8080") 44 | if err != nil { 45 | fmt.Println("dial error:", err) 46 | return 47 | } 48 | defer conn.Close() 49 | 50 | buf := make([]byte, 4096) // big buffer 51 | var c int 52 | for { 53 | c++ 54 | n, err := conn.Read(buf) 55 | if err != nil { 56 | if err != io.EOF { 57 | fmt.Println("read error:", err) 58 | } 59 | break 60 | } 61 | fmt.Println(c, "Received message:", n, string(buf)) 62 | } 63 | fmt.Println(string(buf)) 64 | } 65 | ``` 66 | ## TCP Server | Publish to web 67 | ```go 68 | func tcpToweb() { 69 | 70 | l, _ := net.Listen("tcp", "127.0.0.1:12345") 71 | defer l.Close() 72 | 73 | for { 74 | // Wait for a connection. 75 | conn, _ := l.Accept() 76 | 77 | go func(c net.Conn) { 78 | //for { 79 | 80 | // msg, err := bufio.NewReader(conn).ReadString('\n') 81 | // if err != nil { 82 | // break 83 | // } 84 | // program := strings.Trim(msg, "\r\n") 85 | 86 | cmd := exec.Command("top", "-bn1") 87 | var b bytes.Buffer 88 | cmd.Stdout = &b 89 | cmd.Run() 90 | //conn.Write(b.Bytes()) 91 | body := b.String() 92 | fmt.Fprint(conn, "HTTP/1.1 200 OK\r\n") 93 | fmt.Fprintf(conn, "Content-Length: %d\r\n", len(body)) 94 | fmt.Fprint(conn, "Content-Type: text/html\r\n") 95 | fmt.Fprint(conn, "\r\n") 96 | fmt.Fprint(conn, body) 97 | 98 | //} 99 | //connection closed 100 | c.Close() 101 | }(conn) 102 | } 103 | } 104 | ``` 105 | -------------------------------------------------------------------------------- /template/about.gohtml: -------------------------------------------------------------------------------- 1 | {{block "middle" .}}About middle page {{.Title}}{{end}} -------------------------------------------------------------------------------- /template/footer.gohtml: -------------------------------------------------------------------------------- 1 | this is footer -------------------------------------------------------------------------------- /template/header.gohtml: -------------------------------------------------------------------------------- 1 | this is header -------------------------------------------------------------------------------- /template/index.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header.gohtml" .}} 2 | 3 |

Hello Gin!

4 | {{range $k, $v := .}} 5 |

{{$k}}={{$v}}

6 | {{end}} 7 | 8 | {{block "middle" .}}{{end}} 9 | 10 | {{template "footer.gohtml" .}} -------------------------------------------------------------------------------- /terms.md: -------------------------------------------------------------------------------- 1 | ## Mutex meaning? 2 | * A programming flag used to grab and release an object. 3 | * Mutex is a program object that prevents simultaneous access to a shared resource. 4 | * Mutex is a locking mechanism used to synchronize access to a resource. 5 | 6 | > Only one task can acquire the mutex. It means there is ownership associated with a mutex, and only the owner can release the lock (mutex). 7 | 8 | > In computer science, mutual exclusion is a property of concurrency control, which is instituted for the purpose of preventing race conditions. 9 | -------------------------------------------------------------------------------- /tooling.md: -------------------------------------------------------------------------------- 1 | ## Go Tooling 2 | 3 | ## Topics to be covered 4 | * Debugging 5 | * Testing 6 | * Profiling 7 | * Tracing 8 | * Unit Test 9 | * [Go-wrk](https://github.com/tsliwowicz/go-wrk) 10 | * [Go-torch](https://github.com/uber/go-torch) 11 | * Benchmark 12 | 13 | ## Go formatting 14 | > gofmt main.go \ 15 | > gofmt -w main.go \ 16 | 17 | ## Cross compilation 18 | > go build \ 19 | > go build -o name \ 20 | > GOOS=linux go build \ 21 | > GOOS=windows go build \ 22 | > file name \ 23 | 24 | ## Compile & Install together ($GOPATH/bin) 25 | > go install \ 26 | > $GOPATH/bin/name 27 | 28 | ## Downloading, Compiling & Installing into $GOPATH/bin 29 | > go get github.com/mateors/reponame \ 30 | > go get -u https://github.com/golang/example/hello 31 | 32 | ## List all of your packages (dependencies) 33 | > go list \ 34 | > go list -f '{{ .Name }}' \ 35 | > go list -f '{{ .Doc }}' \ 36 | > go list -f '{{ .Imports }}' \ 37 | > go list -f '{{ .Imports }}' strings \ 38 | > go list -f '{{ join .Imports "\n" }}' strings \ 39 | > go list -f '{{ join .Imports "\n" }}' strings \ 40 | 41 | ## Go Documentation 42 | > go doc strings \ 43 | > go doc strings Compare \ 44 | 45 | ## Viewing documentation in the browser 46 | > go doc -http := 8080 47 | 48 | ## Basic Webserver 49 | 50 | 51 | 52 | ## Reference 53 | * [Go Tooling in Action](https://www.youtube.com/watch?v=uBjoTxosSys) 54 | * https://github.com/tsliwowicz/go-wrk 55 | * https://github.com/uber/go-torch 56 | -------------------------------------------------------------------------------- /usql.md: -------------------------------------------------------------------------------- 1 | # USQL 2 | 3 | > `go install github.com/xo/usql@latest` 4 | 5 | ## Building 6 | When building usql out-of-the-box with go build or go install, only the base drivers for PostgreSQL, MySQL, SQLite3, Microsoft SQL Server, Oracle, CSVQ will be included in the build: 7 | 8 | ### build/install with base drivers (PostgreSQL, MySQL, SQLite3, Microsoft SQL Server, Oracle, CSVQ) 9 | > `go install github.com/xo/usql@master` 10 | 11 | * `\drivers` 12 | * \conninfo 13 | 14 | ## connect to a mysql database 15 | * $ usql my://user:pass@host/dbname 16 | * $ usql mysql://user:pass@host:port/dbname 17 | * $ usql my:// 18 | * $ usql /var/run/mysqld/mysqld.sock 19 | 20 | > `usql my://mostain:ateors32s1@localhost/master_host` 21 | 22 | > \echo Welcome `echo $USER` -- 'currently:' "(" `date` ")" 23 | 24 | > `usql --help` 25 | 26 | > `usql -J my://mostain:123ateorsM@localhost/master_host` 27 | 28 | > `usql --json my://mostain:Mateors321@localhost/master_host` 29 | 30 | > `\d login` 31 | 32 | ### Other databases can be enabled by specifying the build tag for their database driver. 33 | > go install -tags 'avatica odbc' github.com/xo/usql@master 34 | -------------------------------------------------------------------------------- /videoedit.md: -------------------------------------------------------------------------------- 1 | # Master Audio & Video Editor 2 | 3 | ## Encode & Decode 4 | * [MPG4 encoder/decoder Go library](https://github.com/mshafiee/mp4) 5 | * [A encoder/decoder class](https://github.com/godeep/mp4) 6 | 7 | ## Resource 8 | * https://github.com/mateors/reisen 9 | * https://github.com/vitali-fedulov/images 10 | * [Image Analysis](https://rosettacode.org/wiki/Percentage_difference_between_images) 11 | * [Percentage_difference](https://rosettacode.org/wiki/Percentage_difference_between_images#Go) 12 | * [Bundle-your-cgo-application](https://medium.com/@maximgradan/how-to-easily-bundle-your-cgo-application-for-windows-8515d2b19f1e) 13 | * [Audio-from-scratch](https://dylanmeeus.github.io/posts/audio-from-scratch-pt4) 14 | --------------------------------------------------------------------------------