第六届字节跳动青训营第八课 | 青训营

64 阅读2分钟

日期:2023年8月25日 主题:学习笔记 - GO语言工程实践课后作业

在GO语言工程实践课程的学习中,我完成了一些课后作业,并记录了实现思路、代码以及路径。以下是我在学习过程中的学习笔记总结:

作业一:实现一个简单的文件服务器

实现思路:

  • 创建一个HTTP服务器,监听指定的端口。
  • 当接收到HTTP请求时,解析请求的路径。
  • 将请求的路径与服务器上的文件路径进行拼接,得到完整的文件路径。
  • 判断文件是否存在,如果存在则读取文件内容,否则返回404错误。
  • 将文件内容作为HTTP响应的正文发送给客户端。

代码实现:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path"
)

func main() {
	http.HandleFunc("/", fileHandler)
	http.ListenAndServe(":8080", nil)
}

func fileHandler(w http.ResponseWriter, r *http.Request) {
	filePath := "." + r.URL.Path
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "File not found")
		return
	}

	if fileInfo.IsDir() {
		filePath = path.Join(filePath, "index.html")
		fileInfo, err = os.Stat(filePath)
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "File not found")
			return
		}
	}

	file, err := os.Open(filePath)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Internal server error")
		return
	}
	defer file.Close()

	content, err := ioutil.ReadAll(file)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "Internal server error")
		return
	}

	w.Header().Set("Content-Type", http.DetectContentType(content))
	w.WriteHeader(http.StatusOK)
	w.Write(content)
}

路径记录:

  • 代码文件路径:/home/user/go/src/file_server/main.go
  • 运行结果:打开浏览器,访问 http://localhost:8080/ ↗ ,可以获取服务器上的文件内容。

作业二:实现一个并发安全的计数器

实现思路:

  • 创建一个结构体类型 Counter ,包含一个整型字段 count 和一个互斥锁 mutex
  • 实现 Counter 结构体的 Increment()Decrement() 方法,分别对 count 字段进行加一和减一的操作。
  • 使用互斥锁来保证多个 goroutine 并发访问时的安全性。

代码实现:

package main

import (
	"fmt"
	"sync"
)

type Counter struct {
	count int
	mutex sync.Mutex
}

func (c *Counter) Increment() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.count++
}

func (c *Counter) Decrement() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.count--
}

func main() {
	counter := Counter{}

	var wg sync.WaitGroup
	wg.Add(100)

	for i := 0; i < 100; i++ {
		go func() {
			defer wg.Done()
			counter.Increment()
		}()
	}

	wg.Wait()

	fmt.Println("Final count:", counter.count)
}

路径记录:

  • 代码文件路径:/home/user/go/src/counter/main.go
  • 运行结果:在终端运行 go run main.go,输出最终的计数器值。

通过完成这些作业,我巩固了GO语言在工程实践中的应用。实践中涉及到了HTTP服务器的搭建和文件处理,以及并发安全的计数器实现。这些练习帮助我深入理解了GO语言的并发模型和标准库的使用。