Language Specification

Report an issue

Subslice

What will be printed when the code below is executed?
Report an issue

Short Declairation

Assuming x is declared and y is not declared, which clauses below are correct?

x, _ := f()
x, _ = f()
x, y := f()
x, y = f()
                        

x, _ := f() //incorrect
x, _ = f() //correct
x, y := f() //correct
x, y = f() //incorrect
                            
Report an issue

Nil Interfaces

What will be printed when the code below is executed? And explain why `println(InitType() == nil)` cannot be compiled?
Report an issue

Map Ok-Idiom

Correct two mistakes in line A and B.

package main

func main() {
	m := make(map[string]int)
	m["a"] = 1
	if v, ok := m["b"]; ok {
		println(v)
	}
}

                            
Report an issue

Pointers

Fill in the blanks in line A and B, to assure the printed output is "foo"

package main

type S struct {
    m string
}

func f() *S {
    return &S{"foo"} //A
}

func main() {
    p := *f()  //B
    print(p.m) //print "foo"
}
                            
Report an issue

interface{} Pointers

In line ABCD, which ones of them have syntax issues?

package main

type S struct {
}

func f(x interface{}) {
}

func g(x *interface{}) {
}

func main() {
    s := S{}
    p := &s
    f(s) //A correct
    g(s) //B incorrect
    f(p) //C correct
    g(p) //D incorrect
}
                            
Report an issue

Temporary Pointer

Explain why the printed output of below are 333, and modify line A to assure 012 is printed.

package main

const N = 3

func main() {
	m := make(map[int]*int)

	for i := 0; i < N; i++ {
		j := int(i)
		m[i] = &j
	}

	for _, v := range m {
		print(*v)
	}
}

                            
Report an issue

Break Outer Loop

Modify the code below, to exit the outer for-loop?

package main

func main() {
outer:
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			print(i, ",", j, " ")
			break outer
		}
		println()
	}
}

                            
Report an issue

Global Varibles

To declare g as a global variable, which clauses below are correct?

var g
var g G
var g = G{}
g := G{}
                        

var g //incorrect
var g G //correct
var g = G{} //correct
g := G{} //incorrect
                            
Report an issue

Defer Stack

Correct a mistake about defer in the code below

package main

import (
	"io/ioutil"
	"os"
)

func main() {
	f, err := os.Open("file")
	if err != nil {
		return
	}
	defer f.Close()

	b, err := ioutil.ReadAll(f)
	println(string(b))
}

                            
Report an issue

Panic Stack

What will be printed when the code below is executed?
Report an issue

recover()

What will be printed when the code below is executed? What will be the exit code after the code below is executed?
Report an issue

Goroutine Closures

What will be printed when the code below is executed? And fix the issue to assure that `len(m)` is printed as 10.

package main

import (
	"sync"
)

const N = 10

func main() {
	m := make(map[int]int)

	wg := &sync.WaitGroup{}
	mu := &sync.Mutex{}
	wg.Add(N)
	for i := 0; i < N; i++ {
		go func(i int) {
			defer wg.Done()
			mu.Lock()
			m[i] = i
			mu.Unlock()
		}(i)
	}
	wg.Wait()
	println(len(m))
}

                            
Report an issue

Type Shadowing

What will be printed when the code below is executed?
Report an issue

String to Bytes

What will be printed when the code below is executed?
Report an issue

Map Mutex

Fix the issue below to avoid "concurrent map writes" error.

package main

import (
	"math/rand"
	"sync"
)

const N = 10

func main() {
	m := make(map[int]int)

	wg := &sync.WaitGroup{}
	mu := &sync.Mutex{}
	wg.Add(N)
	for i := 0; i < N; i++ {
		go func() {
			defer wg.Done()
			mu.Lock()
			m[rand.Int()] = rand.Int()
			mu.Unlock()
		}()
	}
	wg.Wait()
	println(len(m))
}

                            
Report an issue

DeepEqual

Explain why the printed output is false? Modify line A to assure the printed output really equals to equality of the values of x and y.

package main

import (
	"fmt"
	"reflect"
)

type S struct {
	a, b, c string
}

func main() {
	x := interface{}(&S{"a", "b", "c"})
	y := interface{}(&S{"a", "b", "c"})
	fmt.Println(reflect.DeepEqual(x, y))
}

                            
Report an issue

Gosched

Add code in line A to assure that the lowercase letters and capital letters are printed consecutively.

package main

import (
	"fmt"
	"runtime"
	"sync"
)

const N = 26

func main() {
	const GOMAXPROCS = 1
	runtime.GOMAXPROCS(GOMAXPROCS)

	var wg sync.WaitGroup
	wg.Add(2 * N)
	for i := 0; i < N; i++ {
		go func(i int) {
			defer wg.Done()
			runtime.Gosched()
			fmt.Printf("%c", 'a'+i)
		}(i)
		go func(i int) {
			defer wg.Done()
			fmt.Printf("%c", 'A'+i)
		}(i)
	}
	wg.Wait()
}

                            
Report an issue

Map Immutability

Explain why the code below cannot compile and fix it.

package main

type S struct {
	name string
}

func main() {
	m := map[string]*S{"x": &S{"one"}}
	m["x"].name = "two"
}

                            
Report an issue

Slice Sorting

Add code to line A to sort s in ascending order

package main

import (
	"fmt"
	"sort"
)

type S struct {
	v int
}

func main() {
	s := []S{{1}, {3}, {5}, {2}}
	sort.Slice(s, func(i, j int) bool { return s[i].v < s[j].v })
	fmt.Printf("%#v", s)
}

                            

Standard library and Packages

Report an issue

init()

What is the execution sequence of init() in the go files below.

// A/a1.go
package A
func init() {
    println("a1")
}
var A1 = ""

// A/a2.go
package A
func init() {
	println("a2")
}
var A2 = ""


// B/b1.go
package B
func init() {
	println("b1")
}
var B1 = ""


// B/b2.go
package B
import "github.com/test/A"
func init() {
	println("b2")
}
func f() {
	_ = A.A2
}
var B2 = ""


// C/main.go
package main
import (
	"github.com/test/B"
)
func main() {
	_ = B.B2
}

                        

a1
a2
b1
b2
                            
Report an issue

json unmarshalling

Fix the issue below to assure result.status is printed as 200

package main

import (
	"encoding/json"
	"fmt"
)

type Result struct {
	Status int `json:"status"`
}

func main() {
	var data = []byte(`{"status": 200}`)
	result := &Result{}

	if err := json.Unmarshal(data, result); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Printf("result=%+v", result)
}

                            
Report an issue

utf8 length

Fix the mistake below to assure the length of utf8 string can be printed correctly.

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	fmt.Println(utf8.RuneCountInString("你好"))
}

                            
Report an issue

regex multiline mode

Fix the regex pattern in line A, to replace all consecutive 0s to one 0 when 0 is the beginning of the line. The expected output is like: 100 0 1 0 1

package main

import (
	"fmt"
	"regexp"
)

func main() {
	s := `100
00
0
1
0

0
1`
	pattern := regexp.MustCompile("(?m:^0(0|\n)*0)")
	s = pattern.ReplaceAllString(s, "0")
	fmt.Println(s)
}

                            
Report an issue

readline

Compare and contrast the functions below for the use case of traversing each line of a text file. fmt.Fscanf() bufio.Reader.ReadLine() bufio.ReadString('\n') bufio.Scanner.Scan()

bufio.Scanner.Scan(): Best suited
fmt.Fscanf(): Only applicable to formated lines
bufio.Reader.ReadLine(): Very low level. May require more invocations when buffer limit is exceeded.
bufio.ReadString('\n'): Cannot handle EOF
                            
Report an issue

Heap

What will be printed when the code below is executed?
Report an issue

context.WithTimeout

What will be printed when the code below is executed?
Report an issue

flag

Fill in the blanks in line A and B, to parse terminal arguments to ip and port, which default to 0.0.0.0 and 8000.

package main

import "flag"
import "fmt"

var ip string
var port int

func init() {
	flag.StringVar(&ip, "ip", "0.0.0.0", "ip address")
	flag.IntVar(&port, "port", 8000, "port number")
}

func main() {
	flag.Parse()
	fmt.Printf("%s:%d", ip, port)
}

                            
Report an issue

text-template

Complete the code in line A, to generate content with text template for at most 3 tiers. The expected output is as follows: A B C D

package main

import (
	"log"
	"os"
	"text/template"
)

func main() {
	const tpl = `{{.Name}}{{range $child := .Children}}
 {{$child.Name}}{{range $grandchild := $child.Children}}
  {{$grandchild.Name}}{{end}}{{end}}
` // A

	type Tree struct {
		Name     string
		Children []Tree
	}
	root := Tree{
		"A", []Tree{
			Tree{"B", []Tree{
				Tree{"C", []Tree{}},
			}},
			Tree{"D", []Tree{}},
		},
	}

	t := template.Must(template.New("tree").Parse(tpl))

	err := t.Execute(os.Stdout, root)
	if err != nil {
		log.Fatalf("executing template:", err)
	}

}

                            
Report an issue

html-template

Compare and contrast html/template and text/template.

html/template and text/template have the same APIs, while html/template has additional security features against attacks like code injection.
                            
Report an issue

http server

Fill in the blanks in line A and B, to respond to any http requests on port 8000 with response "hello"

package main

import (
	"fmt"
	"net/http"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "hello")
	})
	http.ListenAndServe(":8000", mux)
}

                            
Report an issue

sql query

Fill in the blanks in line ABCD, to print out all the rows and potential errors.

age := 27
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
        log.Fatal(err)
}
defer ___ // A
for ___ { //B
        var name string
        if err := ___; err != nil { //C
                log.Fatal(err)
        }
        fmt.Printf("%s is %d\n", name, age)
}
if err := ___; err != nil { //D
        log.Fatal(err)
}
                        

age := 27
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
        log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
        var name string
        if err := rows.Scan(&name); err != nil {
                log.Fatal(err)
        }
        fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
        log.Fatal(err)
}
                            

Toolchain

Report an issue

gcflags

Explain the meaning of the following options of gcflags

-l:
-m:
-N:
                        

-l:disable function inlining
-m:show the escape analysis and the choice of inlining
-N:disable optimization
                            
Report an issue

benchmark

Explain how b.N is determined.

func BenchmarkFib10(b *testing.B) {
	for n := 0; n < b.N; n++ {
		Fib(10)
	}
}
                        

The value of b.N will increase each time until the benchmark runner is satisfied with the stability of the benchmark.
                            
Report an issue

package management

How doesn go package management tools(i.e. godep, govendor) segregate dependencies from $GOPATH?

Go package management tools save dependencies in ./vendor/ which is introduced from 1.6 in order to include project-specific dependencies without polluting the global $GOPATH
                            
Report an issue

GOMAXPROCS

What will be printed when the code below is executed? Will it be different when line A is changed to `GOMAXPROCS=2` ?

When GOMAXPROCS=1, the printed output will be a-zA-Z.
When GOMAXPROCS=2, a-z will be mixed with A-Z.
                            
Report an issue

shared object

1. Compile str.go to shared object(str.so). 2. Fill in the blanks in line A and B to call function `UpperCase(string) string`.

// str.go
package main

import "strings"

func UpperCase(s string) string {
	return strings.ToUpper(s)
}


// main.go
package main

import (
	"fmt"
	"log"
	"plugin"
)

func main() {
	p, err := plugin.Open("str.so")
	if err != nil {
		log.Panicf("plugin.Open: %s\n", err)
	}
	f, err := ___ // A
	if err != nil {
		log.Panicf("Lookup UpperCase: %s\n", err)
	}
	UpperCase, ok := ___ // B
	if !ok {
		log.Panicf("UpperCase assertion: %s\n", err)
	}
	s := UpperCase("hello")
	fmt.Println(s)
}

                        

go build -buildmode=plugin -o str.so str.go

package main

import (
	"fmt"
	"log"
	"plugin"
)

func main() {
	p, err := plugin.Open("str.so")
	if err != nil {
		log.Panicf("plugin.Open: %s\n", err)
	}
	f, err := p.Lookup("UpperCase")
	if err != nil {
		log.Panicf("Lookup UpperCase: %s\n", err)
	}
	UpperCase, ok := f.(func(string) string)
	if !ok {
		log.Panicf("UpperCase assertion: %s\n", err)
	}
	s := UpperCase("hello")
	fmt.Println(s)
}

                            
Report an issue

GODEBUG

Briefly explain the meaning of the following options of GODEBUG GODEBUG=gctrace=1,schedtrace=1000

Print the debug info of gc and go scheduler's states every 1000ms
                            
Report an issue

$GOROOT vs $GOPATH

What is $GOROOT and $GOPATH?

$GOROOT is the root directory for standard library, including executables, source code and docs.
$GOPATH is the directory for 3rd party packages.
                            
Report an issue

go generate

Briefly describe how go generate works.

go generate will search specified directories or files for comments like "//go:generate", and replace with the output of the execution of the given shell commands, and flush the final content to stdout.
                            
Report an issue

http server的pprof

Briefly describe how to use pprof to monitor the performance of http server.

Add `import _ "net/http/pprof"` in the main.go
Run the following commands to get info correspondingly:
CPU profile:
go tool pprof http://localhost:6060/debug/pprof/profile --second N
heap profile:
go tool pprof http://localhost:6060/debug/pprof/heap
goroutine blocking profile:
go tool pprof http://localhost:6060/debug/pprof/block
                            
Report an issue

./...

What is the meaning of "./..." in the terminal commands?

It is the wildcard stands for .(current directory) and all its subdirectories recursively.
                            

Internals

Report an issue

String Internals

Fill in the blank in line A, to convert b from []byte to string without causing memory copy. The expected output is "143"

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var b = []byte("123")
	s := *(*string)(unsafe.Pointer(&b))

	b[1] = '4'
	fmt.Printf("%+v\n", s) //print 143
}

                            
Report an issue

Slice Internals

Fill in the blank in line A, to assure that printOriginalSlice will print the original slice of a subslice

package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

const M = 10
const N = 5

func printOriginalSlice(subslice *[]int) {
	data := (*[M]int)(unsafe.Pointer(((*reflect.SliceHeader)(unsafe.Pointer(subslice))).Data))

	fmt.Printf("original\t%p:%+v\n", data, *data)
}

func main() {
	slice := make([]int, M)
	for i, _ := range slice {
		slice[i] = i
	}
	subslice := slice[0:N]

	fmt.Printf("slice\t%p:%+v\n", &slice, slice)
	fmt.Printf("subslice\t%p:%+v\n", &subslice, subslice)
	printOriginalSlice(&subslice)
}

                            
Report an issue

defer overhead

What is the overhead of defer?

runtime.deferproc and runtime.deferreturn cause context copy and retrieval on stack memory
                            
Report an issue

Map malloc Threshold

What is the malloc threshold of Map object? How to modify it?

The default limit is 128.
It can be modified by changing the value of maxKeySize and maxValueSize in runtime.hashmap
                            
Report an issue

runtime.newobject()

What does runtime.newobject() do? Does make() and `new` operation always invoke runtime.newobject()?

runtime.newobject() is to allocate heap memory.
make() and `new` operation will not invoke runtime.newobject() when it is inlined or optimized.
                            
Report an issue

SSA

Briefly introduce the benefits of SSA(Static Single Assignment) form.

Remove unnecessary code
Remove redundant varibles and logics
Optimize register or memory allocation
Transform varibles to constants when possible
Transform "high cost" instructions to "low cost"
                            
Report an issue

AST

What will be printed when the code below is executed?(Hint: Use the template below) *ast.File: ____: ____ *ast.GenDecl: *ast.ValueSpec: ____: ____ ____: ____
Report an issue

Go Bootstrapping

Briefly describe the bootstrapping process of a go executable.

Run the platform-specific assembly that is located under $GOROOT/src/runtime/
runtime·args(): Parse terminal arguments
runtime·osinit(): Initialize CPU cores
runtime·schedinit(): Initialize goroutine scheduler, stack memory, terminal arguments, environment variables, debug parameter, gc, GOMAXPROCS, ...
runtime·mstart(): Start gc monitor, enable gc, import dependencies and run init() functions, finally run main.main()

                            
Report an issue

Unbuffered and Buffered Channels

What are the differences between unbuffered and buffered channels?

For unbuffered channel, the sender will block on the channel until the receiver receives the data from the channel, whilst the receiver will also block on the channel until sender sends data into the channel. 
Compared with unbuffered counterpart, the sender of buffered channel will block when there is no empty slot of the channel, while the receiver will block on the channel when it is empty.
                            
Report an issue

Destructor

What is the destructor in go?

There is no destructor in go. But runtime.SetFinalizer() can set a callback function for a pointer.
                            
Report an issue

Garbage Collection

Briefly describe how gc works in go?

MarkWorker goroutine recursively scan all the objects and colors them into white(inaccessible), gray(pending), black(accessible). But finally they will only be black and white objcts.
In compile time, the compiler has already injected a snippet called write barrier to monitor all the modifications from any goroutines to heap memory.
When "Stop the world" is performed, scheduler hibernates all threads and preempt all goroutines.
Garbage collector will recycle all the inaccessible objects so heap or central can reuse.
If the whole span of memory are unused, it can be freed to OS.
Perform "Start the world" to wake cpu cores and threads, and resume the execution of goroutines.
                            
Report an issue

Goroutine Sleep

What is the difference between C.sleep() and time.Sleep()?

C.sleep() invokes syscall sleep, which causes idle threads
time.Sleep() is optimized for goroutine so syscall sleep is not involved.
                            
Report an issue

Memory Allocation

Briefly introduce the strategies that how go runtime allocates memory.

For small objects(<=32KB), go runtime starts with cache firstly, then central, and finally heap.
For big objects(>32KB), directly from heap.
                            
Report an issue

Stack vs Heap

When go runtime allocates memory from heap, and when from stack?

For small objects whose life cycle is only within the stack frame, stack memory is allocated.
For small objects that will be passed across stack frames, heap memory.
For big objects(>32KB), heap memory.
For small objects that could escape to heap but actually inlined, stack memory.
                            
Report an issue

Goroutine Pause or Halt

List the functions can stop or suspend the execution of current goroutine, and explain their differences.

runtime.Gosched: give up CPU core and join the queue, thus will be executed automatically.
runtime.gopark: blocked until the callback function unlockf in argument list return false.
runtime.notesleep: hibernate the thread.
runtime.Goexit: stop the execution of goroutine immediately and call defer, but it will not cause panic.