编辑
2023-09-22
英语学习
00

This is a question from Quora.

Is it true that many people in schools regard computer science students in universities as free computer repairers for granted, but what they learn is quite different from computer repair?

中文翻译

“是否有很多学校的人都认为大学的计算机科学专业学生可以免费为他们修理计算机,然而他们所学的与计算机维修完全不同?”

  • regard:认为
  • computer science:计算机科学
  • students:学生
  • universities:大学
  • free:免费
  • computer repairers:计算机维修员
  • for granted:理所当然地
  • learn:学习
  • quite different:完全不同的

Yes and yes. And it’s not absurd; you might ask your English major friend for help editing a paper. It’s not necessarily a good idea, though, in both cases. I can guarantee that computer science students learn little to nothing about computer repair in the computer science courses (this isn’t necessarily true at a community college, though). If they know anything, it’s out of personal experience, interest, or a part-time job. And if you ask a friend for a favor, be respectful about it and either “pay back” when you can, or do something nice for them.

中文翻译

"是的,这是事实。这并不荒谬;你可能会向你的英语专业朋友寻求帮助来编辑一篇论文。但在这两种情况下,这未必是一个好主意。我可以保证,在计算机科学课程中,计算机科学专业的学生很少或几乎不学习与计算机维修有关的内容(尽管在社区大学可能不一样)。如果他们了解任何东西,那可能是出于个人经验、兴趣或兼职工作。如果你向朋友请求帮忙,请尊重对方,并在有机会时“回报”,或者为他们做一些好事。"

编辑
2023-09-22
动漫
00

The moments that moved Clannad

编辑
2023-09-22
linux
00

HTTP状态码表示客户端HTTP请求的返回结果、标记服务器端的处理是否正常或者是出现的错误,能够根据返回的状态码判断请求是否得到正确的处理很重要。 状态码分类表

类别 原因短语 1xx Informational(信息性状态码) 接受的请求正在处理 2xx Success(成功状态码) 请求正常处理完毕 3xx Redirection(重定向) 需要进行附加操作以完成请求 4xx Client error(客户端错误) 客户端请求出错,服务器无法处理请求 5xx Server Error(服务器错误) 服务器处理请求出错 一些常见的状态码为:

200 - 服务器成功返回网页 404 - 请求的网页不存在 500 - 服务器遇到错误,无法完成请求 详细分解:

1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码。

代码 说明 100 (继续) 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

2xx (成功) 表示成功处理了请求的状态代码。

代码 说明 200 (成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。 201 (已创建) 请求成功并且服务器创建了新的资源。 202 (已接受) 服务器已接受请求,但尚未处理。 203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。 205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。 206 (部分内容) 服务器成功处理了部分 GET 请求。

编辑
2023-09-22
后端
00

HTTP响应状态码500表示"Internal Server Error",指示服务器在处理请求时发生了意外的错误,导致无法完成请求。

当您收到HTTP响应状态码500时,表明服务器端遇到了问题,无法正常处理请求。这可能是由以下几个常见原因引起的:

  1. 代码错误:服务器端的应用程序或脚本中可能存在错误,导致无法正确处理请求。这可能包括语法错误、逻辑错误、资源访问问题等。

  2. 服务器配置问题:服务器的配置可能存在问题,例如无效的配置选项、不兼容的组件或模块等,导致请求无法被正确处理。

  3. 资源不可用:服务器所需的某些资源可能无法访问或不可用,例如数据库连接失败、文件系统权限问题等。

解决HTTP 500错误的方法包括:

编辑
2023-09-22
后端
00

主题思路

上次简单演示了一下SSE使用,接下来使用SSE来实现一个发布订阅模式,主体逻辑大概如下,服务端负责维护一个主题集合,主题可以由任何人通过POST请求来创建,订阅者发送一个GET请求,包含要订阅的主题名,然后和服务端建立一个SSE连接,开始接收消息,发布者发送一个POST请求,包含主题名和需要发布的消息,服务端收到发布者发布的信息,将这条信息推送给所有订阅了这个主题的人。代码实现也很简单,为了简化实现,我们用gin来实现。

接下来先来定义一下主题

go
type Topic struct { Name string Subscribers map[string]chan<- string }

其中每个订阅者都有一个消息发送通道,消息会先到chan,后面到订阅时候通过轮询队列来发送信息

go
type PubSubServer struct { Topics map[string]*Topic } func NewPubSubServer() *PubSubServer { return &PubSubServer{ Topics: make(map[string]*Topic), } }

服务实例。接下来定义三个路由

go
pubSubServer := NewPubSubServer() router := gin.Default() router.POST("/topic", pubSubServer.createTopicHandler) router.GET("/subto", pubSubServer.subscribeHandler) router.POST("/pushto", pubSubServer.pushToTopicHandler) log.Println("PubSub server started on port 8000") log.Fatal(router.Run(":8000"))

这就是主函数逻辑,在代码中我会尽量使用英文,为了提升英语能力,这三个路由主要是创建主题,订阅主题,发布主题。

接下来是代码主体

go
func (ps *PubSubServer) createTopicHandler(c *gin.Context) { topicName := c.PostForm("TopicName") if topicName == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "TopicName is required"}) return } _, exists := ps.Topics[topicName] if exists { c.JSON(http.StatusBadRequest, gin.H{"error": "Topic already exists"}) return } topic := &Topic{ Name: topicName, Subscribers: make(map[string]chan<- string), } ps.Topics[topicName] = topic c.JSON(http.StatusCreated, gin.H{"message": fmt.Sprintf("Topic created: %s", topicName)}) } func (ps *PubSubServer) subscribeHandler(c *gin.Context) { topicName := c.Query("TopicName") if topicName == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "TopicName is required"}) return } topic, exists := ps.Topics[topicName] if !exists { c.JSON(http.StatusBadRequest, gin.H{"error": "Topic does not exist"}) return } messageChan := make(chan string) topic.Subscribers[c.ClientIP()] = messageChan c.Header("Content-Type", "text/event-stream") c.Header("Cache-Control", "no-cache") c.Header("Connection", "keep-alive") c.Header("Access-Control-Allow-Origin", "*") // Write the response to the HTTP response stream flusher, _ := c.Writer.(http.Flusher) for { select { case message := <-messageChan: // Write message to response stream fmt.Fprintf(c.Writer, "data: %s\n", message) // Refresh the response stream and send data to the client flusher.Flush() case <-c.Writer.CloseNotify(): delete(topic.Subscribers, c.ClientIP()) log.Printf("Subscriber disconnected: %s", c.ClientIP()) return } } } func (ps *PubSubServer) pushToTopicHandler(c *gin.Context) { topicName := c.PostForm("TopicName") if topicName == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "TopicName is required"}) return } topic, exists := ps.Topics[topicName] if !exists { c.JSON(http.StatusBadRequest, gin.H{"error": "Topic does not exist"}) return } message := c.PostForm("Message") if message == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Message is required"}) return } for _, subscriber := range topic.Subscribers { subscriber <- message } c.JSON(http.StatusOK, gin.H{"message": "Message pushed to topic"}) }

以上代码都很简单,不多讲解,接下来实现一个简单的基于命令行的客户端,

go
package main import ( "bufio" "fmt" "io" "log" "net/http" "net/url" "os" "strings" ) func main() { reader := bufio.NewReader(os.Stdin) for { fmt.Println("Select an action:") fmt.Println("1. Create a topic") fmt.Println("2. Subscribe to a topic") fmt.Println("3. Push a message to a topic") fmt.Println("0. Exit") input, _ := reader.ReadString('\n') input = strings.TrimSpace(input) switch input { case "1": createTopic(reader) case "2": subscribeToTopic(reader) case "3": pushMessageToTopic(reader) case "0": fmt.Println("Exiting...") return default: fmt.Println("Invalid input. Please try again.") } } } func createTopic(reader *bufio.Reader) { fmt.Print("Enter the topic name: ") topicName, _ := reader.ReadString('\n') topicName = strings.TrimSpace(topicName) data := url.Values{} data.Set("TopicName", topicName) resp, err := http.PostForm("http://localhost:8000/topic", data) if err != nil { fmt.Println("Error creating topic:", err) return } defer resp.Body.Close() if resp.StatusCode == http.StatusCreated { fmt.Println("Topic created successfully") } else { fmt.Println("Error creating topic:", resp.Status) } } func subscribeToTopic(reader *bufio.Reader) { // 获取订阅主题 fmt.Print("Enter the topic name: ") topicName, _ := reader.ReadString('\n') topicName = strings.TrimSpace(topicName) // 构建查询参数 queryParams := url.Values{} queryParams.Set("TopicName", topicName) // 创建 SSE 连接 url := "http://localhost:8000/subto?" + queryParams.Encode() req, err := http.NewRequest("GET", url, nil) if err != nil { log.Fatal("Error creating request:", err) } req.Header.Set("Accept", "text/event-stream") client := &http.Client{} fmt.Println("开始做") resp, err := client.Do(req) fmt.Println("做完了") if err != nil { log.Fatal("Error connecting to server:", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Fatal("Failed to subscribe to topic:", resp.Status) } go readEvents(resp.Body) select {} } func readEvents(body io.Reader) { reader := bufio.NewReader(body) for { line, err := reader.ReadString('\n') if err != nil { log.Fatal("Error reading event:", err) } fmt.Println("Received event:", line) } } func pushMessageToTopic(reader *bufio.Reader) { fmt.Print("Enter the topic name: ") topicName, _ := reader.ReadString('\n') topicName = strings.TrimSpace(topicName) fmt.Print("Enter the message to push: ") message, _ := reader.ReadString('\n') message = strings.TrimSpace(message) data := url.Values{} data.Set("TopicName", topicName) data.Set("Message", message)