Monday, December 14, 2015

The Go Programming Language



Disadvantages:

https://www.quora.com/What-are-the-advantages-and-disadvantages-of-Golang
  • Built-in concurrencyThere are no heavy threads but channels.
Compiled
  • There is no VM. It compiles directly to the machine code (if we exclude Go’s intermediary assembly) which is fast, fast and fast (did I say fast?).
  • Fast compilation. The programming language design is built for fast compilation in mind from the beginning.
  • Compiles cross-platform to OS X, Linux, Windows,  and many others.
  • Creates only one executable file output after the compilation without any dependencies, so that you can upload it anywhere which Go supports and just run it. Or just compile it there after you upload the code. No dependency hell.
Safe
  • Strong and static typed.
  • Err everywhere. You need to check errors for each of the error producing function in your code explicitly. However, I love the explicitness of Go programs. In the upcoming years maybe we’d find an elegant solution for this. There are some proposals to change error handling.
    too many boilerplate code

    len("a") vs "a".length(), the latter is much IDE friendly, easier to code.

    go build aSourceFile.go - create a statically linked executable file

    There is another way to execute your Go code that does not create any permanent executable files—it just generates some intermediate files that are automatically deleted afterwards.

    go run aSourceFile.go
    - You either use a Go package or do not include it
    Go has strict rules about package usage. Therefore, you cannot just include any package that you might think you will need and not use it afterwards

    Using an underscore character in front of a package name in the import list will not create an error message in the compilation process, even if that package is not used in the program:

        _ "os"
    Go requires the use of semicolons as statement terminators in many contexts, and the compiler automatically inserts the required semicolons when it thinks that they are necessary. Therefore, putting the opening brace ({) in its own line will make the Go compiler insert a semicolon at the end of the previous line (func main()), which produces the error message.

    You can delete the intermediate files of a downloaded Go package as follows:
    $ go clean -i -v -x github.com/mactsouk/go/simpleGitHub

    Additionally, file descriptor 0 can be accessed as /dev/fd/0 on a macOS machine

    os.Stdin, os.Stdout, and os.Stderr

    The official name for := is the short assignment statement. The short assignment statement can be used in place of a var declaration with an implicit type.

    The var keyword is mostly used for declaring global variables in Go programs as well as for declaring variables without an initial value. The reason for the former is that every statement that exists outside of the code of a function must begin with a keyword, such as func or var. This means that the short assignment statement cannot be used outside of a function because it is not available there.

        var f *os.File
        f = os.Stdin
        defer f.Close()

        scanner := bufio.NewScanner(f)
        for scanner.Scan() {
            fmt.Println(">", scanner.Text())
        }

    On macOS machines, the name of the process is syslogd(8). On the other hard, most Linux machines use rsyslogd(8)

    https://www.jetbrains.com/help/go/install-and-set-up-product.html
    Created a workspace where you keep projects.
    Use the following layout:
    • work
      • bin
      • pkg
      • src
        • github.com
          • user_name
            • project1
            • project2
    https://stackoverflow.com/questions/40744063/go-project-setup-using-intellij
    • Create a main .go file and make sure package name is main, and a main function exists.
    https://stackoverflow.com/questions/20722502/whats-a-good-best-practice-with-go-workspaces
    I think it's easier to have one $GOPATH per project, that way you can have different versions of the same package for different projects, and update the packages as needed.
    With a central repository, it's difficult to update a package as you might break an unrelated project when doing so (if the package update has breaking changes or new bugs).
    https://www.quora.com/What-is-the-best-IDE-to-use-for-Go


      1. Microsoft’s Visual Studio Code with the vscode-go extension, it features:
      https://corner.squareup.com/2014/05/evaluating-go-frameworks.html
      TL;DR: We recommend just using the net/http package in the standard library to start. And if you want help with request routing we recommend looking at Gorilla and Gocraft/web. Both Revel andMartini have too much dependency injection and other magic to make us feel comfortable. Gorilla is the most minimal.
      https://medium.com/@PierreZ/why-you-really-should-give-golang-a-try-6b577092d725#.65mg3r3h3
      Gofmt is a tool that automatically formats Go source code, so your code’ll look like others. Pretty convenient to read go code.

      func main() {
          http.HandleFunc(
              "/",
              func(w http.ResponseWriter, r *http.Request) {
                  fmt.Fprintln(w, "Hello, gophers!")
              },
          )
          http.ListenAndServe(":8080", nil)
      }

      Great package management
      For example, if we need a dependency, we just need to put it on top like this:
      package main
      import (
          “encoding/json”
          “net/http”
          “github.com/gorilla/mux”
      )
      Just run “go get” and it’s over. Really. No more Maven, Gradle, Ant build fails. No makefile, build.xml and horrible stuff like that.

      http://denis.papathanasiou.org/posts/2015.12.26.post.html
      I recently participated in the following programming challenge:
      Write a program to test user reflexes: when it runs, it waits a random amount of time between 1 and 10 seconds, and prints "GO!" as a prompt. 

      It then expects the user to hit the enter key, and times how fast enter is pressed, in milliseconds. 

      If the enter key is pressed before the "GO!" prompt appears, the program prints "FAIL".
      package main
      import (
      "bufio"
      "fmt"
      "math/rand"
      "os"
      "time"
      )
      func init() {
      rand.Seed(time.Now().UnixNano())
      }
      func main() {
      channel := make(chan time.Time)
      go func() {
      reader := bufio.NewReader(os.Stdin)
      reader.ReadString('\n')
      channel <- time.Now()
      }()
      time.Sleep(time.Second * time.Duration(rand.Intn(11)))
      paused := time.Now()
      fmt.Println("GO!")
      entered := <- channel
      if paused.Sub(entered) > 0 {
      fmt.Println("FAIL")
      } else {
      fmt.Printf("%v\n", time.Since(entered))
      }
      }
      http://www.codeceo.com/article/go-create-window.html
      Go语言富有表现力,简洁,干净,高效。它的并发机制使得它可以很容易地编写让多核和网络化的计算机发挥最大作用的程序,同时其新型的类型系统使得灵活且模块化的程序结构变得可能。Go语言能够快速编译为机器码,并具备垃圾回收的便利以及运行时反射的能力。这是一个快速、静态类型的编译语言,并且让人感觉像动态类型和解释型的语言。
      Go源文件中的第一条语句必须是包的名称。由于我们要写的程序是一个可执行程序,所以包的名称必须是main。它告诉Go编译器这个包应编译为可执行程序,而不是一个共享库:
      package main

      https://github.com/a8m/go-lang-cheat-sheet

      Functions As Values And Closures

      func main() {
          // assign a function to a name
          add := func(a, b int) int {
              return a + b
          }
          // use the name to call the function
          fmt.Println(add(3, 4))
      }
      
      // Closures, lexically scoped: Functions can access values that were
      // in scope when defining the function
      func scope() func() int{
          outer_var := 2
          foo := func() int { return outer_var}
          return foo
      }
      
      func another_scope() func() int{
          // won't compile because outer_var and foo not defined in this scope
          outer_var = 444
          return foo
      }
      
      
      // Closures: don't mutate outer vars, instead redefine them!
      func outer() (func() int, int) {
          outer_var := 2
          inner := func() int {
              outer_var += 99 // attempt to mutate outer_var from outer scope
              return outer_var // => 101 (but outer_var is a newly redefined
                               //         variable visible only inside inner)
          }
          return inner, outer_var // => 101, 2 (outer_var is still 2, not mutated by foo!)
      }
      https://www.golang-book.com/books/intro/9
       A struct is a type which contains named fields. For example we could represent a Circle like this:
      type Circle struct {
        x float64
        y float64
        r float64
      }
      The type keyword introduces a new type. It's followed by the name of the type (Circle), the keyword struct to indicate that we are defining a struct type and a list of fields inside of curly braces.
      Method
      func (c *Circle) area() float64 {
        return math.Pi * c.r*c.r
      }
      In between the keyword func and the name of the function we've added a “receiver”. The receiver is like a parameter – it has a name and a type.
      Embedded Types
      This would work, but we would rather say an Android is a Person, rather than an Android has a Person. Go supports relationships like this by using an embedded type. Also known as anonymous fields, embedded types look like this:
      type Android struct {
        Person
        Model string
      }
      We use the type (Person) and don't give it a name. When defined this way the Person struct can be accessed using the type name:
      a := new(Android)
      a.Person.Talk()
      But we can also call any Person methods directly on the Android:
      a := new(Android)
      a.Talk()

      type Shape interface {
        area() float64
      }

      The Go Programming Language
      https://github.com/adonovan/gopl.io
      Package main is special. It defines a standalone executable program, not a library. Within package main the function main is also special—it’s where execution of the program begins. Whatever main does is what the program does.

      GOROOT=/usr/local/go
      go run helloworld.go
      go build helloworld.go

      program will not compile if there are missing imports or if there are unnecessary ones. This strict requirement prevents references to unused packages from accumulating as programs evolve.

      Go takes a strong stance on code formatting. The gofmt tool rewrites code into the standard format, and the go tool’s fmt subcommand applies gofmt to all the files in the specified package, or the ones in the current directory by default.

      A related tool, goimports, additionally manages the insertion and removal of import declarations as needed
      package main

      import (
          "fmt"
          "os"
      )

      func main() {
          var s, sep string
          for i := 1; i < len(os.Args); i++ {
              s += sep + os.Args[i]
              sep = " "
          }
          fmt.Println(s)
      }
      If it is not explicitly initialized, it is implicitly initialized to the zero value for its type

      The := symbol is part of a short variable declaration, a statement that declares one or more variables and gives them appropriate types based on the initializer values;
      func main() {
          s, sep := "", "" // The first form, a short variable declaration, is the most compact, but it may be used only within a function, not for package-level variables.
          for _, arg := range os.Args[1:] {
              s += sep + arg
              sep = " "
          }
          fmt.Println(s)
      }

      var s string
      fmt.Println(strings.Join(os.Args[1:], " "))
      fmt.Println(os.Args[1:])

          counts := make(map[string]int)
          input := bufio.NewScanner(os.Stdin)
          for input.Scan() {
              counts[input.Text()]++
          }
          // NOTE: ignoring potential errors from input.Err()
          for line, n := range counts {
              if n > 1 {
                  fmt.Printf("%d\t%s\n", n, line)
              }
          }

          files := os.Args[1:]
          if len(files) == 0 {
              countLines(os.Stdin, counts)
          } else {
              for _, arg := range files {
                  f, err := os.Open(arg)
                  if err != nil {
                      fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
                      continue
                  }
                  countLines(f, counts)
                  f.Close()
              }
          }  
      func countLines(f *os.File, counts map[string]int) {
          input := bufio.NewScanner(f)
          for input.Scan() {
              counts[input.Text()]++
          }
          // NOTE: ignoring potential errors from input.Err()
      }

      import "io/ioutil"
      func countLines(f *os.File, counts map[string]int) {
          input := bufio.NewScanner(f)
          for input.Scan() {
              counts[input.Text()]++
          }
          // NOTE: ignoring potential errors from input.Err()
      }

      Goroutines and Channels
      communicating sequential processes or CSP, a model of concurrency in which values are passed between independent activities (goroutines) but variables are for the most part confined to a single activity.


      func main() {
        go spinner(100 * time.Millisecond)
        const n = 45
        fibN := fib(n) // slow
        fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
      }

      func spinner(delay time.Duration) {
        for {
          for _, r := range `-\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
          }
        }
      }

      func fib(x int) int {
        if x < 2 {
          return x
        }
        return fib(x-1) + fib(x-2)
      }

      func handleConn(c net.Conn) {
        defer c.Close()
        for {
          _, err := io.WriteString(c, time.Now().Format("15:04:05\n"))
          if err != nil {
            return // e.g., client disconnected
          }
          time.Sleep(1 * time.Second)
        }
      }

      func main() {
        listener, err := net.Listen("tcp", "localhost:8000")
        if err != nil {
          log.Fatal(err)
        }
        //!+
        for {
          conn, err := listener.Accept()
          if err != nil {
            log.Print(err) // e.g., connection aborted
            continue
          }
          go handleConn(conn) // handle connections concurrently
        }
        //!-
      }


      Channels
      If goroutines are the activities of a concurrent Go program, channels are the connections between them. A channel is a communication mechanism that lets one goroutine send values to another goroutine. Each channel is a conduit for values of a particular type, called the channel’s element type.


      ch <- x  // a send statement

      x = <-ch // a receive expression in an assignment statement
      <-ch     // a receive statement; result is discarded


      UNBUFFERED CHANNELS
      A send operation on an unbuffered channel blocks the sending goroutine until another goroutine executes a corresponding receive on the same channel, at which point the value is transmitted and both goroutines may continue. Conversely, if the receive operation was attempted first, the receiving goroutine is blocked until another goroutine performs a send on the same channel.

      func main() {
          conn, err := net.Dial("tcp", "localhost:8000")
          if err != nil {
              log.Fatal(err)
          }
          done := make(chan struct{})
          go func() {
              io.Copy(os.Stdout, conn) // NOTE: ignoring errors
              log.Println("done")
              done <- struct{}{} // signal the main goroutine
          }()
          mustCopy(conn, os.Stdin)
          conn.Close()
          <-done // wait for background goroutine to finish
      }

      PIPELINES
      func main() {
          naturals := make(chan int)
          squares := make(chan int)

          // Counter
          go func() {
              for x := 0; ; x++ {
                  naturals <- x
              }
          }()

          // Squarer
          go func() {
              for {
                  x := <-naturals
                  squares <- x * x
              }
          }()

          // Printer (in main goroutine)
          for {
              fmt.Println(<-squares)
          }
      }


      func main() {
          naturals := make(chan int)
          squares := make(chan int)

          // Counter
          go func() {
              for x := 0; x < 100; x++ {
                  naturals <- x
              }
              close(naturals)
          }()

          // Squarer
          go func() {
              for x := range naturals {
                  squares <- x * x
              }
              close(squares)
          }()

          // Printer (in main goroutine)
          for x := range squares {
              fmt.Println(x)
          }
      }

      The type chan<- int, a send-only channel of int, allows sends but not receives. Conversely, the type <-chan int, a receive-only channel of int, allows receives but not sends. (The position of the <- arrow relative to the chan keyword is a mnemonic.)

      func mirroredQuery() string {
          responses := make(chan string, 3)
          go func() { responses <- request("asia.gopl.io") }()
          go func() { responses <- request("europe.gopl.io") }()
          go func() { responses <- request("americas.gopl.io") }()
          return <-responses // return the quickest response
      }

      func request(hostname string) (response string) { /* ... */ }
      Had we used an unbuffered channel, the two slower goroutines would have gotten stuck trying to send their responses on a channel from which no goroutine will ever receive. This situation, called a goroutine leak, would be a bug. Unlike garbage variables, leaked goroutines are not automatically collected, so it is important to make sure that goroutines terminate themselves when no longer needed.

      func makeThumbnails3(filenames []string) {
          ch := make(chan struct{})
          for _, f := range filenames {
              go func(f string) {
                  thumbnail.ImageFile(f) // NOTE: ignoring errors
                  ch <- struct{}{}
              }(f)
          }

          // Wait for goroutines to complete.
          for range filenames {
              <-ch
          }
      }

      Level Up Your Web Apps With Go
      import (
        "fmt"
        "net/http"
      )

      func main() {
        http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
          w.Header().Add("Server", "Go Server")
          fmt.Fprintf(w, `
          <html>
            <body>
              Hello Gopher
            </body>
          </html>`)
        })

        http.ListenAndServe(":3000", nil)
      }

      ServeMux is a request multiplexer, which handles matching an incoming request’s URL against the registered handlers and calling the handler for the pattern that most closely matches the URL. The http package creates a default ServeMux instance for you, and the http.HandleFunc function is actually a shortcut to the (*ServeMux) HandleFunc method on that default ServeMux.

      There are two types of patterns: a path and a subtree. A path is defined without a trailing backslash (/), and refers to an explicit path. Subtrees are designed to match the start of a path, and include the trailing /

      THE HANDLER INTERFACE
      type Handler interface {
          ServeHTTP(ResponseWriter, *Request)
      }

      // UptimeHandler writes the number of seconds since starting to the response.
      type UptimeHandler struct {
        Started time.Time
      }

      func NewUptimeHandler() UptimeHandler {
        return UptimeHandler{Started: time.Now()}
      }

      func (h UptimeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(
          w,
          fmt.Sprintf("Current Uptime: %s", time.Since(h.Started)),
        )
      }

      // SecretTokenHandler secures a request with a secret token.
      type SecretTokenHandler struct {
        next   http.Handler
        secret string
      }

      // ServeHTTP makes SecretTokenHandler implement the http.Handler interface.
      func (h SecretTokenHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
        // Check the query string for the secret token
        if req.URL.Query().Get("secret_token") == h.secret {
          // The secret token matched, call the next handler
          h.next.ServeHTTP(w, req)
        } else {
          // No match, return a 404 Not Found response
          http.NotFound(w, req)
        }
      }

      func main() {
        http.Handle("/", SecretTokenHandler{
          next:   NewUptimeHandler(),
          secret: "MySecret",
        })

        http.ListenAndServe(":3000", nil)
      }

      Labels

      Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

      Popular Posts