mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 04:48:29 +08:00
更新14、15和17章目录 (#702)
* 更新14、15和17章目录 * Update README.md * 添加章节序号 * 添加章节序号 * 添加代码链接 * 修改错别字 * 删除多余字符 * 修复代码与文件不对应的问题 * 修改代码
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
## 翻译进度
|
||||
|
||||
14.9 [实现 Futures 模式](eBook/14.9.md)
|
||||
18.11 [出于性能考虑的最佳实践和建议](eBook/18.11.md)
|
||||
|
||||
## 支持本书
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
客户端-服务器应用正是 goroutines 和 channels 的亮点所在。
|
||||
|
||||
客户端(Client)可以是运行在任意设备上的任意程序,它会按需发送请求(request)至服务器。服务器(Server)接收到这个请求后开始相应的工作,然后再将响应(response)返回给客户端。典型情况下一般是多个客户端(既多个请求)对应一个(或少量)服务器。例如我们日常使用的浏览器客户端,其功能就是向服务器请求网页。而Web服务器则会向浏览器响应网页数据。
|
||||
客户端(Client)可以是运行在任意设备上的任意程序,它会按需发送请求(request)至服务器。服务器(Server)接收到这个请求后开始相应的工作,然后再将响应(response)返回给客户端。典型情况下一般是多个客户端(即多个请求)对应一个(或少量)服务器。例如我们日常使用的浏览器客户端,其功能就是向服务器请求网页。而Web服务器则会向浏览器响应网页数据。
|
||||
|
||||
使用Go的服务器通常会在协程中执行向客户端的响应,故而会对每一个客户端请求启动一个协程。一个常用的操作方法是客户端请求自身中包含一个通道,而服务器则向这个通道发送响应。
|
||||
|
||||
@@ -35,7 +35,7 @@ func run(op binOp, req *Request) {
|
||||
req.replyc <- op(req.a, req.b)
|
||||
}
|
||||
```
|
||||
`server`协程会无限循环以从`chan \*Request`接收请求,并且为了避免被长时间操作所堵塞,它将为每一个请求启动一个协程来做具体的工作:
|
||||
`server`协程会无限循环以从`chan *Request`接收请求,并且为了避免被长时间操作所堵塞,它将为每一个请求启动一个协程来做具体的工作:
|
||||
|
||||
```go
|
||||
func server(op binOp, service chan *Request) {
|
||||
@@ -112,26 +112,22 @@ func run(op binOp, req *Request) {
|
||||
req.replyc <- op(req.a, req.b)
|
||||
}
|
||||
|
||||
func server(op binOp, service chan *Request, quit chan bool) {
|
||||
func server(op binOp, service chan *Request) {
|
||||
for {
|
||||
select {
|
||||
case req := <-service:
|
||||
go run(op, req)
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
req := <-service // requests arrive here
|
||||
// start goroutine for request:
|
||||
go run(op, req) // don't wait for op
|
||||
}
|
||||
}
|
||||
|
||||
func startServer(op binOp) (service chan *Request, quit chan bool) {
|
||||
service = make(chan *Request)
|
||||
quit = make(chan bool)
|
||||
go server(op, service, quit)
|
||||
return service, quit
|
||||
func startServer(op binOp) chan *Request {
|
||||
reqChan := make(chan *Request)
|
||||
go server(op, reqChan)
|
||||
return reqChan
|
||||
}
|
||||
|
||||
func main() {
|
||||
adder, quit := startServer(func(a, b int) int { return a + b })
|
||||
adder := startServer(func(a, b int) int { return a + b })
|
||||
const N = 100
|
||||
var reqs [N]Request
|
||||
for i := 0; i < N; i++ {
|
||||
@@ -149,9 +145,9 @@ func main() {
|
||||
fmt.Println("Request ", i, " is ok!")
|
||||
}
|
||||
}
|
||||
quit <- true
|
||||
fmt.Println("done")
|
||||
}
|
||||
|
||||
```
|
||||
## 14.10.2 卸载(Teardown):通过信号通道关闭服务器
|
||||
|
||||
|
@@ -23,7 +23,7 @@ func DoPart(sem chan int) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
runtime.GOMAXPROCS = NCPU
|
||||
runtime.GOMAXPROCS(NCPU) // runtime.GOMAXPROCS = NCPU
|
||||
DoAll()
|
||||
}
|
||||
|
||||
|
@@ -117,7 +117,7 @@ func BuildLazyIntEvaluator(evalFunc EvalFunc, initState Any) func() int {
|
||||
9th even: 18
|
||||
```
|
||||
|
||||
练习14.12:general_lazy_evaluation2.go
|
||||
练习14.12:[general_lazy_evaluation2.go](exercises/chapter_14/general_lazy_evalution2.go)
|
||||
通过使用14.12中工厂函数生成前10个斐波那契数
|
||||
|
||||
提示:因为斐波那契数增长很迅速,使用`uint64`类型。
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# defer 模式
|
||||
# 17.2 defer 模式
|
||||
|
||||
使用 `defer` 可以确保资源不再需要时,都会被恰当地关闭或归还到“池子”中。更重要的一点是,它可以恢复 panic。
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# 可见性模式
|
||||
# 17.3 可见性模式
|
||||
|
||||
我们在 [4.2.1节](04.2.md) 见过简单地使用可见性规则控制对类型成员的访问,他们可以是 Go 变量或函数。[10.2.1节](10.2.md) 展示了如何在单独的包中定义类型时,强制使用工厂函数。
|
||||
|
||||
|
@@ -145,12 +145,27 @@
|
||||
- 14.7 [新旧模型对比:任务和worker](14.7.md)
|
||||
- 14.8 [惰性生成器的实现](14.8.md)
|
||||
- 14.9 [实现 Futures 模式](14.9.md)
|
||||
|
||||
- 14.10 [复用](14.10.md)
|
||||
- 14.11 [限制同时处理的请求数](14.11.md)
|
||||
- 14.12 [链式协程](14.12.md)
|
||||
- 14.13 [在多核心上并行计算](14.13.md)
|
||||
- 14.14 [并行化大量数据的计算](14.14.md)
|
||||
- 14.15 [漏桶算法](14.15.md)
|
||||
- 14.16 [对Go协程进行基准测试](14.16.md)
|
||||
- 14.17 [使用通道并发访问对象](14.17.md)
|
||||
- 第15章:[网络、模版与网页应用](15.0.md)
|
||||
- 15.1 [tcp服务器](15.1.md)
|
||||
- 15.2 [一个简单的web服务器](15.2.md)
|
||||
- 15.3 [访问并读取页面数据](15.3.md)
|
||||
- 15.4 [写一个简单的网页应用](15.4.md)
|
||||
- 15.5 [确保网页应用健壮](15.5.md)
|
||||
- 15.6 [用模板编写网页应用](15.6.md)
|
||||
- 15.7 [探索 template 包](15.7.md)
|
||||
- 15.8 [精巧的多功能网页服务器](15.8.md)
|
||||
- 15.9 [用 rpc 实现远程过程调用](15.9.md)
|
||||
- 15.10 [基于网络的通道 netchan](15.10.md)
|
||||
- 15.11 [与 websocket 通信](15.11.md)
|
||||
- 15.12 [用 smtp 发送邮件](15.12.md)
|
||||
|
||||
## 第四部分:实际应用
|
||||
|
||||
@@ -166,7 +181,10 @@
|
||||
- 16.9 [闭包和协程的使用](16.9.md)
|
||||
- 16.10 [糟糕的错误处理](16.10.md)
|
||||
- 第17章:[模式](17.0.md)
|
||||
- 17.1 [关于逗号ok模式](17.1.md)
|
||||
- 17.1 [逗号ok模式](17.1.md)
|
||||
- 17.2 [defer 模式](17.2.md)
|
||||
- 17.3 [可见性模式](17.3.md)
|
||||
- 17.4 [运算符模式和接口](17.4.md)
|
||||
- 第18章:[出于性能考虑的实用代码片段](18.0.md)
|
||||
- 18.1 [字符串](18.1.md)
|
||||
- 18.2 [数组和切片](18.2.md)
|
||||
|
Reference in New Issue
Block a user