len() 函数会返回什么? do { ... } while i < 5
for _,c := range "hello" { ... }
for i := 1; i < 5; i++ { ... }
for i < 5 { ... }
Explanation: Go 只有 for 循环。
values := []int{1, 1, 2}
values.append(3)
values.insert(3, 3)
append(values, 3)
values = append(values, 3)
Explanation: 在 Go 中切片是不可变的,因此调用 append 不会修改原切片。
Read 的值是多少?const (
Write = iota
Read
Execute
)
import "github/gin-gonic/gin"
import "https://github.com/gin-gonic/gin"
import "../template"
import "github.com/gin-gonic/gin"
package main
var GlobalFlag string
func main() {
print("["+GlobalFlag+"]")
}
GlobalFlag 从未被初始化。[]。"[" +nil+"]" 也是 nil。GlobalFlag 从未被初始化。myVar 在模块 myModule 中的包 myPackage 的某个文件里、所有函数之外声明,那么它可以从哪里被访问?myPackage 内的任何地方都可以访问,myModule 的其它部分不行。myModule 的应用都可以访问。myModule 的任意位置访问。myModule 中其他包只要导入了 myPackage 就可以访问。Explanation: 若要让该变量在 myPackage 之外可用,请将名称改为 MyVar。
另请参阅 Go 之旅中的导出名称示例。
go test 打印它正在运行的测试?go testgo test -xgo test --verbosego test -v{0, 0}。你如何修复它?type Point struct {
x int
y int
}
func main() {
data := []byte(`{"x":1, "y": 2}`)
var p Point
if err := json.Unmarshal(data, &p); err != nil {
fmt.Println("error: ", err)
} else {
fmt.Println(p)
}
}
json.Decoderdata 的指针X 和 Y 导出(大写)sync.Mutex 处于加锁状态时,它会阻塞什么?Mutex 的任何其它加锁调用sync.Mutex 会加锁,使得同一时间只有一个 goroutine 可以访问被保护的变量。int 和 Mutex,并在它们返回时计数。select 语句上循环。sync.WaitGroupExplanation: 这正是 sync.WaitGroup 的用途——在 Golang 中使用 sync.WaitGroup
select 语句中使用 time.After 的副作用是什么?select 语句中使用且没有副作用。select 语句直到时间过去。注意:它不会阻塞
select,也不会阻塞其他通道。
select 语句用于什么?func Add(a, b int) int {
return a + b
}
A
// Calculate a + b
// - a: int
// - b: int
// - returns: int
func Add(a, b int) int {
return a + b
}
B
// Does a + b
func Add(a, b int) int {
return a + b
}
C
// Add returns the sum of a and b
func Add(a, b int) int {
return a + b
}
D
// returns the sum of a and b
func Add(a, b int) int {
return a + b
}
Explanation: 文档注释应当以函数名开头。
i := myVal.(int),myVal 的类型限制是什么?myVal 必须是整数类型,例如 int、int64、int32 等。myVal 必须能够被断言为 int。myVal 必须是一个接口(interface)。myVal 必须是数值类型,例如 float64 或 int64。Explanation: 这种使用 .(type) 的类型断言只用于接口。
// +build windows 注释。_ 前缀。// +build windows 注释。
//go:build windows“Go 1.16 及更早版本使用不同的构建约束语法,前缀为// +build。当遇到旧语法时,gofmt 会添加等效的//go:build约束。”
data := "A group of Owls is called a parliament"
resp, err := http.Post("https://httpbin.org/post", "text/plain", []byte(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", data)
resp, err := http.Post("https://httpbin.org/post", "text/plain", strings.NewReader(data))
resp, err := http.Post("https://httpbin.org/post", "text/plain", &data)
Save() error 的接口,惯用的命名是什么?switch 语句_它自己的词法块(lexical block)。每个 case 语句_一个额外的词法块相关文章摘录:
第二个 if 语句嵌套在第一个 if 语句内部,因此在第一个 if 中声明的变量对第二个 if 可见。
switch中也有类似规则:除了条件的词法块外,每个case还拥有自己的词法块。
Unmarshal 函数在大小写敏感性上的默认行为是什么?相关文章摘录:
将 JSON 解组到结构体时,
Unmarshal会将传入对象的键与Marshal使用的键(结构体字段名或其标签)进行匹配,更倾向于精确匹配,但也接受大小写不敏感的匹配。默认情况下,没有对应结构体字段的对象键将被忽略(另见Decoder.DisallowUnknownFields)。
time 包中 Time.Sub() 与 Time.Add() 的区别是什么?Time.Add() 用于做加法,而 Time.Sub() 用于嵌套时间戳。Time.Add() 总是返回更晚的时间,而 time.Sub 总是返回更早的时间。Time.Add(x) 等价于 Time.Sub(-x)。Time.Add() 接受 Duration 参数并返回 Time,而 Time.Sub() 接受 Time 参数并返回 Duration。recover 方法在什么地方有用?main 函数里相关文章摘录:
只有在延迟执行的函数内部调用
recover才有用。在延迟函数内部执行recover会通过恢复正常执行来停止正在进行的 panic 序列,并获取传给panic的错误信息。如果在延迟函数之外调用recover,它不会停止 panic 序列。
println(message)log.New(os.Stderr, "", 0).Println(message)fmt.Errorf("%s\n", message)fmt.Fprintln(os.Stderr, message)func New(out io.Writer, prefix string, flag int) *Logger;参数 out 用于设置日志数据的输出目标。Errorf 根据格式化说明符进行格式化,并将字符串作为值返回。func Fprintln(w io.Writer, a ...any) (n int, err error);Fprintln 使用操作数的默认格式并写入到 w。go.mod 中使用 replace 指令。go mod edit -replace example.com/greetings=../greetings。go.mod 的 replace 指令go test allgo run --allgo test .go test ./...相关文章摘录:
也允许使用相对模式,例如
go test ./...来测试所有子目录。
相关文章摘录:
简而言之,Go 源码是 UTF-8,因此字符串字面量的源码是 UTF-8 文本。
相关文章摘录:
encoding包定义了字符编码(如 Shift JIS 和 Windows 1252)的接口,可与 UTF-8 相互转换。
t.Run 内部,t.Fatal 的行为有什么不同?t.Fatal 不会导致测试工具崩溃,从而保留输出信息。t.Fatal 会停止该子测试的执行,并继续运行其他测试用例。t.Fatal 会停止所有测试,并包含关于失败子测试的额外信息。
Fatal等价于先Log再FailNow。Log使用默认格式化参数记录文本到错误日志。FailNow将函数标记为失败,并通过调用runtime.Goexit停止其执行(随后会运行当前 goroutine 中所有延迟调用)。执行将继续到下一个测试或基准。FailNow必须在运行测试或基准函数的 goroutine 中调用,而不是在测试期间创建的其它 goroutine 中调用。调用FailNow不会停止那些其它 goroutine。Run将f作为t的一个名为name的子测试运行。它在单独的 goroutine 中运行f并阻塞直到f返回或调用t.Parallel成为并行测试。Run会报告f是否成功(或至少在调用t.Parallel之前没有失败)。 可以从多个 goroutine 同时调用Run,但所有这些调用必须在外层测试函数返回之前返回。
log.Fatal 做了什么?panic。panic。相关文章摘录:
Fatal等价于先Print(),然后调用os.Exit(1)。
相关文章摘录:
Year: "2006" "06"
Month: "Jan" "January" "01" "1"
Day of the week: "Mon" "Monday"
Day of the month: "2" "_2" "02"
Day of the year: "__2" "002"
Hour: "15" "3" "03" (PM or AM)
Minute: "4" "04"
Second: "5" "05"
AM/PM mark: "PM"
err)?log.Error(err)log.Printf("error: %v", err)log.Printf(log.ERROR, err)log.Print("error: %v", err)Explanation: 在 Go 的 log 包 中既没有 log.ERROR 也没有 log.Error();log.Print() 的参数处理方式类似 fmt.Print();log.Printf() 的参数处理方式类似 fmt.Printf()。
go test 命令会把哪些文件名识别为测试文件?test 开头的文件test 这个词的文件_test.go 结尾的文件_test.go 结尾的文件ch := make(chan int)
ch <- 7
val := <-ch
fmt.Println(val)
Go Playground 分享,输出:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox2282523250/prog.go:7 +0x37
Program exited.
ch := make(chan int)
close(ch)
val := <-ch
fmt.Println(val)
Go 语言规范 “接收操作符”,相关文章摘录:
从已关闭的通道进行接收的操作总能立即继续执行,在接收了所有已发送的值之后,会得到该元素类型的零值。
Go Playground 分享,输出:
0
Program exited.
var stocks map[string]float64 // stock -> price
price := stocks["MSFT"]
fmt.Printf("%f\n", price)
Go Playground 分享,输出:
0.000000
Program exited.
cmd 目录,并在其中为每个可执行文件创建一个子目录。main。pkg 目录,并在其中为每个可执行文件创建一个子目录。main.go 编译为可在 OSX arm64 上运行的可执行文件?print Hello Gopher! 的正确语法是?go(fmt.Println("Hello Gopher!"))go func() { fmt.Println("Hello Gopher!") }go fmt.Println("Hello Gopher!")Go fmt.Println("Hello Gopher!")for range 循环中迭代一个 map,键值对会以什么顺序访问?String() stringfunc findUser(ctx context.Context, login string) (*User, error) {
ch := make(chan *User)
go func() {
ch <- findUserInDB(login)
}()
select {
case user := <-ch:
return user, nil
case <-ctx.Done():
return nil, fmt.Errorf("timeout")
}
}
sync.WaitGroup。ch 设为带缓冲通道。select 添加一个 default 分支。runtime.SetFinalizer。相关文章摘录:
解决该泄漏的最简单方式是把通道从无缓冲改为容量为 1 的带缓冲通道。这样在超时场景下,接收方离开后,goroutine 仍能把
*User值放入通道,然后返回。
var i int8 = 120
i += 10
fmt.Println(i)
Go Playground 示例,输出:
-126
Program exited.
worker 的定义,启动一个 goroutine 调用 worker 并将结果发送到名为 ch 的通道,正确的语法是?func worker(m Message) Result
go func() {
r := worker(m)
ch <- r
}
go func() {
r := worker(m)
r -> ch
} ()
go func() {
r := worker(m)
ch <- r
} ()
go ch <- worker(m)
package os
type FilePermission int
type userID int
type 和 struct 语句。generate 命令做什么?sql、json、yaml 子命令以及 --schema、--objects 开关来生成相关代码。_generate.go 结尾的文件,然后分别编译并运行这些文件。//go:generate 注释,并为每个注释运行其指定的终端命令。mocks 和 tests 子命令来生成相应的 .go 源文件。time 包,如何获得从现在起 90 分钟后的时间?time.Now().Add(90)time.Now() + (90 * time.Minute)time.Now() + 90time.Now().Add(90 * time.Minute)wg.Wait() 之后立刻添加 close(ch)。make(chan, int) 添加第二个参数,例如 make(chan int, 5)。WaitGroup 调用,例如所有以 wg 开头的行。wg.Add(1) 之后移动到 wg.Wait() 之前。相关文章摘录:
解决该泄漏的最简单方式是把通道从无缓冲改为容量为 1 的带缓冲通道。这样在超时场景下,接收方离开后,goroutine 仍能把
*User值放入通道,然后返回。
encoding/json 之后,你将如何访问 Marshal 函数?encoding.json.Marshalencoding/json.MarshalMarshaljson.Marshalcontext.Context 为这个发起 GET 请求的 HTTP 客户端实现 3 秒超时,缺失的两段代码是什么?package main
import (
"context"
"fmt"
"net/http"
)
func main() {
var cancel context.CancelFunc
ctx := context.Background()
// #1: <=== 这里应当写什么?
req, _ := http.NewRequest(http.MethodGet,
"https://linkedin.com",
nil)
// #2: <=== 这里应当写什么?
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Println("Request failed:", err)
return
}
fmt.Println("Response received, status code:",
res.StatusCode)
}
ctx.SetTimeout(3*time.Second)
req.AttachContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel()
req = req.WithContext(ctx)
ctx, cancel = context.WithTimeout(ctx, 3*time.Second); defer cancel() #2: req.AttachContext(ctx)
ctx.SetTimeout(3*time.Second)
req = req.WithContext(ctx)
Client 的结构体,如何导出一个带有默认值的变量,使其可以被其他包访问?
let Default := new Client()
public default = &Client()
var Default = &Client{}
export default := new Client{}
{Master Chief Spartan Protagonist Halo}。怎样让它输出 Master Chief - a Spartan - is the Protagonist of Halo?package main
import "fmt"
type Character struct{
Name string
Class string
Role string
Game string
}
func main() {
mc := Character{
Name: "Master Chief",
Class: "Spartan",
Role: "Protagonist",
Game: "Halo",
}
fmt.Println(mc)
}
A
// 替换
// fmt.Println(mc)
// 为:
fmt.Printf("(?P<Name>) - a (?P<Class>) - is the (?P<Role>) of (?P<Game>)", mc)
B
// 替换
// fmt.Println(mc)
// 为:
fmt.Println(mc, func(c Character) string {
return c. Name + " - a " + c.Class + " - is the " + c.Role + " of " + c.Game
})
C
// 在包 `main` 中添加:
func (c Character) String() string {
return fmt.Sprintf("%s - a %s - is the %s of %s", c.Name, c.Class, c.Role,c.Game)
}
D
// 在包 `main` 中添加:
func (c Character) OnPrint() {
fmt.Println(" - a - is the of ")
}
Clients 实现一个可用的 Append() 方法?package main
type Client struct {
Name string
}
type Clients struct {
clients []*Client
}
func main() {
c:= &Clients{clients.make([]*Client,0)}
c.Append(&Client{Name: "LinkedIn API})
}
A
func (cc *Clients) Append(c *Client) {
cc.clients = append(cc.clients, c)
}
B
func (cc *Clients) Append(c *Client) {
cc.append(c)
}
C
func (cc Clients) Append(c Client) {
cc.clients = append(cc.clients, c)
}
D
func (cc *Clients) Append(c Client) {
cc.clients.append(c)
}
panic() 中恢复,同时不让程序失败?假设你的答案将在发生 panic 的同一作用域内运行。用返回类型为 panic 的匿名函数包裹该函数调用,并在其后加 () 调用它,然后内省返回的 panic 实例来处理错误。
使用 try{ ... } 包裹调用语句,并在 catch{ ... } 中处理错误。
在发生错误的函数调用之前使用 defer func { ... }(),并在匿名函数内部处理该 panic。
在函数调用前加前缀 @,强制把 panic 作为 error 返回,然后像处理普通 error 一样处理。
var n int
fmt.Println (n)
因为在 Go 中,当变量被声明但未显式初始化时,会被赋予基于其类型的默认零值。对于整数
n来说,零值是 0。
String() string 方法,应使用哪个动词?在 Go 中,
%s用于格式化字符串。当用于定义了String()方法的自定义类型时,会自动调用String(),其返回值将用于该格式化字符串。
time.Now().Format(layout) 时,下面哪个不是合法的 layout 值?根据文档,值 1 和 01 代表当前月份。
each layout string is a representation of the time stamp,
Jan 2 15:04:05 2006 MST
An easy way to remember this value is that it holds, when presented in this order, the values (lined up with the elements above):
1 2 3 4 5 6 -7
Namespace 必须实现接口 JSONConverter?假设答案写在声明 Namespace 的同一个包中。该语法创建一个类型为
JSONConverter的变量_,并将(*Namespace)(nil)赋给它。这实质上检查了Namespace是否满足JSONConverter接口。
implements 关键字声明其实例可以用于任何被该接口类型化的变量、参数或返回值位置。在 Go 中,只要一个类型实现了接口的所有方法,它就自动满足该接口;无需显式声明“实现了某接口”。
===[Output]================
1: &{GameId:1 Title:Wolfenstein YearReleased:1992}
2: &{GameId:2 Title:Doom YearReleased:1993}
3: &{GameId:3 Title:Quake YearReleased:1996}
===[main.go]================
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
type Game struct {
GameId int
Title string
YearReleased int
}
func main() {
conn, err := sql.Open("mysql",
"john_carmack:agiftw!@tcp(localhost:3306)/idsoftware")
if err != nil {
panic(err)
}
defer func() { _ = conn.Close() }()
results, err := conn.Query("SELECT game_id,title,year_released FROM games;")
if err != nil {
panic(err)
}
defer func() { _ = results.Close() }()
// #1 <=== What goes here?
for results.Next() {
var g Game
// #2 <=== What goes here?
if err != nil {
panic(err)
}
// #3 <=== What goes here?
}
for i, g := range games {
fmt.Printf("%d: %+v\n", i, g)
}
}
#1: games := make([]*Game, results.RowsAffected())
#2: g, err = results.Fetch()
#3: games[results.Index()] = &g
#1: games := []Game{}
#2: g, err = results.Fetch()
#3: games = append(games,g)
#1: games := map[int]Game{}
#2: err = results.Scan(&g)
#3: games[g.GameId] = g
#1: games := make(map[int]*Game, 0)
#2: err = results.Scan(&g.GameId, &g.Title, &g.YearReleased)
#3: games[g.GameId] = &g
存放在该包的 /test/ 子目录中
接受 testing.Tester 参数的函数
编写名称匹配 ^Subtest 的函数
调用 testing.AssertionFailed
以 _test.go 结尾
函数名匹配 ^Test[A-Z]
调用 t.Run()
调用 t.Errorf()
以 test_ 开头
函数匹配 [a-z]Test$
调用 testing.Subtest()
允许 testing.Assert() 断言失败
存放在项目根目录的 /test/ 子目录
接受 testing.Test 参数的函数
传递闭包给 testing.AddSubtest()
从函数返回一个 error
rune 是哪种类型的别名?相关文章摘录:
Go 语言将
rune定义为int32类型的别名,这样当整数值表示一个码点时,程序可以更清晰。
:= 语法给多个变量赋值?例如:x, err := myFunc()
cpu.pprof 的 profiler 输出?go pprof -to SVG cpu.profgo tool pprof -http=:8080 cpu.pprofgo tool pprof cpu.pprofgo tool trace cpu.pprofinterface{} 类型的变量会被判断为 nil?nil 时。nil 时。nil。若字符串变量已分配但未赋值,其默认值是空字符串
""。在 Go 中,未初始化的字符串变量会被自动赋予其类型的零值。
panicraiseExceptionexit内置函数
panic()会触发 panic,停止正常执行流程并开始“恐慌”过程;若不被恢复,程序将终止。
a,b := 1, 2
b,c:= 3, 4
fmt.Println(a, b, c)
| [ ] |
funclambdafunc()anonymousExplanation: 它们可以在使用处内联定义,提供了更灵活的代码组织方式。
functionName(){}call functionName(){}func(){}()execute func(){}type Example int(但不是 int)、type Example struct{...}(但不是 struct)等。struct、map、slice 的类型,例如 type Example struct{…}struct 的类型,例如 type Example struct{...}方法可以为任何非内置的具名类型定义。通过
type声明创建的新类型是具名类型,可以为其定义方法;但不能直接为内置类型(如int、string等)附加方法。参考