如何用Golang学习后端开发

如何用Golang学习后端开发 大家好!

希望大家一切顺利!

我在学习如何用Go语言(或者说用任何编程语言)构建实际应用程序时遇到了一些困难。我感觉自己被海量的信息淹没了,不知道如何有效地继续下去。

以下是我面临的一些具体挑战:

  1. 从哪里开始? 当我打开编辑器并创建 main.go 文件时,我常常会盯着屏幕很长时间,不知道下一步该做什么。我尝试写点东西,但最终感到卡住并筋疲力尽。
  2. 令人困惑的资源: 我尝试搜索文章和教程,但它们常常通过引入大量包和函数让事情变得更加混乱。我被各种方法和结构弄得不知所措,不清楚它们是如何组合在一起的。

我知道不止我一个人有这些困扰,因为我以前能够学习算法并觉得可以掌握。然而,实际应用程序似乎有更多的“包装”和复杂性,尤其是涉及到像 bufioionet/http 这样的内置包时。

对于你们可能有的任何建议或策略来克服这些挑战,我将由衷地感激。我相信其他人也遇到过类似的问题,并且可能找到了有效的解决方法。

谢谢!


更多关于如何用Golang学习后端开发的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

先尝试做些事情。强烈推荐 Coding Challenges,从中挑选你感兴趣的内容,深入理解其概念,然后尝试用 Go(或任何你想学习的语言)来实现它 =)

更多关于如何用Golang学习后端开发的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你说得对,谢谢。我原本想创建一个基础的CRUD应用,但即使是从哪里开始也让我感到不知所措 :dotted_line_face:,比如文件结构、如何连接数据库(又要用Docker吗?)。

不过,现在我想我会先忽略所有这些,直接在 main.go 里开始一切,使用SQLite,并且只为每个端点打印一些消息。

从简单的开始。我已经多次给出这个建议,但一个仅供自己使用的简单任务追踪应用程序是一个有趣的入门方式。当我学习一个新的框架或任何东西时,我经常创建一个任务追踪应用(就像我前段时间为了学习Flutter而构建了一个)。试着找出一些听起来有趣的东西来构建,然后就去构建它!在我看来,除了结构化的学习环境之外,这是最好的学习方式。

你好,

我留言是想让你放心。我是一个彻头彻尾的初学者,对Go语言一无所知,数学也完全不在行,但我想试一试,我来到这里是因为我相信这是可能的。我仍然感到不知所措,因为我做了很多(网上的)研究,但今天我决定开始。

如果你谈论的是后端,那意味着你甚至可以教我 🙂 请放心,并遵循那些已经回复的好心人的建议。

我真诚地感谢你的帖子,并祝你一切顺利。 谢谢!

HW

ab-dauletkhan: 你说得对,谢谢。我本来想创建一个基础的 CRUD 应用,但即使是从那里开始也感到不知所措,比如文件结构、如何连接数据库(又要用 Docker 吗?)。

是的,一开始就构建奔驰或特斯拉这样的大项目,就像要吞下一头大象。而 Docker 可能不是你首先要考虑学习的东西?

但是,现在我想我会忽略所有这些,直接在 main.go 中开始一切,使用 sqlite,然后为每个端点打印一些消息。

即使使用 Sqlite 作为起点也可能让人不知所措。我认为,先做端点,之后再添加 Sqlite。除此之外,如果不知道如何让它在互联网上运行,你就无法学习后端开发。

ab-dauletkhan:

我在学习如何使用 Golang(或者说任何编程语言)构建实际应用程序时遇到了一些困难。我发现海量的信息让我不知所措,并且不确定如何有效地继续下去。

对我来说,Web 应用意味着 Web 服务器和数据库连接。后端是 Web 应用的一部分,但也涉及许多其他方面。例如 HTML 模板,它既是后端,也涉及一点前端。

  1. 我从哪里开始? 当我打开编辑器并开始编写 main.go 时,我常常发现自己盯着屏幕很长时间,不知道下一步该做什么。我尝试写点什么,但最终感到卡住并筋疲力尽。

我是从最简单的东西开始的。“hello world”。但即使这样也是一个挑战,因为你必须设置一个服务器并管理后端的后端。这个 hello world 程序托管在 IONOS 每月 1GBP 的 VPS XS 上。

  1. 令人困惑的资源: 我尝试搜索文章和教程,但它们常常通过引入大量包和函数使事情变得更加混乱。我被各种方法和结构搞得不知所措,却不知道它们是如何组合在一起的。

在我看来,没有个人目标地去搜索是浪费时间。先决定要构建什么,然后再采取下一步。一小步一小步地来…

如何用Golang学习后端开发

1. 从具体项目开始

不要从空白文件开始,先确定一个简单的项目目标。比如创建一个HTTP API服务器:

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

func main() {
    http.HandleFunc("/users", usersHandler)
    log.Println("Server starting on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func usersHandler(w http.ResponseWriter, r *http.Request) {
    users := []User{
        {ID: 1, Name: "Alice"},
        {ID: 2, Name: "Bob"},
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(users)
}

2. 理解核心包的实际用法

net/http为例,先掌握基本模式:

// 路由处理
http.HandleFunc("/api/health", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("OK"))
})

// 中间件模式
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s", r.Method, r.URL.Path)
        next(w, r)
    }
}

// 使用goroutine处理并发
http.HandleFunc("/async", func(w http.ResponseWriter, r *http.Request) {
    go func() {
        // 异步处理任务
        processTask()
    }()
    w.Write([]byte("Task started"))
})

3. 数据库操作示例

使用标准库database/sql

import (
    "database/sql"
    _ "github.com/lib/pq"
)

func connectDB() *sql.DB {
    db, err := sql.Open("postgres", "host=localhost user=postgres dbname=test sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    return db
}

func queryUsers(db *sql.DB) ([]User, error) {
    rows, err := db.Query("SELECT id, name FROM users")
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    var users []User
    for rows.Next() {
        var u User
        if err := rows.Scan(&u.ID, &u.Name); err != nil {
            return nil, err
        }
        users = append(users, u)
    }
    return users, nil
}

4. 文件操作示例

使用bufioio包:

import (
    "bufio"
    "os"
)

func readFileLines(filename string) ([]string, error) {
    file, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    
    var lines []string
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        lines = append(lines, scanner.Text())
    }
    return lines, scanner.Err()
}

func writeToFile(filename, content string) error {
    file, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer file.Close()
    
    writer := bufio.NewWriter(file)
    _, err = writer.WriteString(content)
    if err != nil {
        return err
    }
    return writer.Flush()
}

5. 完整的REST API示例

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "strconv"
    "github.com/gorilla/mux"
)

var users = map[int]User{
    1: {ID: 1, Name: "John"},
    2: {ID: 2, Name: "Jane"},
}

func main() {
    r := mux.NewRouter()
    
    r.HandleFunc("/users", getUsers).Methods("GET")
    r.HandleFunc("/users/{id}", getUser).Methods("GET")
    r.HandleFunc("/users", createUser).Methods("POST")
    
    log.Fatal(http.ListenAndServe(":8080", r))
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(users)
}

func getUser(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id, _ := strconv.Atoi(vars["id"])
    
    if user, exists := users[id]; exists {
        json.NewEncoder(w).Encode(user)
    } else {
        http.Error(w, "User not found", http.StatusNotFound)
    }
}

func createUser(w http.ResponseWriter, r *http.Request) {
    var user User
    if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    users[user.ID] = user
    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(user)
}

6. 并发处理示例

func processRequests(requests []string) []string {
    results := make([]string, len(requests))
    var wg sync.WaitGroup
    
    for i, req := range requests {
        wg.Add(1)
        go func(idx int, request string) {
            defer wg.Done()
            results[idx] = handleRequest(request)
        }(i, req)
    }
    
    wg.Wait()
    return results
}

func handleRequest(req string) string {
    // 模拟处理逻辑
    time.Sleep(100 * time.Millisecond)
    return "Processed: " + req
}

从具体功能开始实现,逐步组合成完整应用。每个包都有明确的用途:net/http处理HTTP,database/sql处理数据库,bufio处理缓冲I/O。先实现核心功能,再考虑错误处理、日志、配置等。

回到顶部