owl’s delusions

A collection of thoughts, ideas, and musings.

WWDC

果子这新的玻璃效果真是一言难尽啊,控制中心虚化搞得看都看不清了 iPadOS 向 macOS 靠拢确实还不错 希望 Intelligence 早点上吧

June 10, 2025 · 🦉

科技爱好周刊351期阅读笔记

惭愧,今天也让 AI 生产了平庸之作 甚至还能模仿我的风格

June 6, 2025 · 🦉

使用 GitHub Copilot 提升代码编写效率

本文由 AI 生成 GitHub Copilot 推出了编程助手功能,可以直接在 GitHub Issues 中 assign 给 @copilot,它会自动分析问题并创建 PR 来解决。 注意:使用 GitHub Copilot 编程助手功能需要 Copilot Pro+ 订阅。 主要功能 GitHub Copilot 编程助手能够: 自动分析 GitHub Issues 中描述的问题 理解代码库的结构和上下文 生成完整的代码解决方案 自动创建 Pull Request 并提交修改 使用方法 创建或找到一个 Issue Assign 给 @copilot 等待 Copilot 分析和处理 检查自动创建的 PR 总结 通过 Issue assign 功能,GitHub Copilot 实现了从问题描述到代码实现的自动化流程,提升开发效率。

June 6, 2025 · 🦉

科技爱好周刊350期阅读笔记

还真有点道理的,我也该研究下怎么可以搞用户订阅,每次有文章更新就发邮件,这样对于想看我博客的人也方便 如果有愿意付费只看精品的,就可以只发包含某些 tag 的文章 Exactly,对 AI 的使用还是很保守,毕竟幻觉问题还是难以解决,而且我也不太想放弃自己的脑子 还记得大学时候在社团里,给学弟学妹们写寄语,我写到虽然不要重复去发明轮子,但照着轮子去做自己的 demo,发明一下三角形四边形也都很重要。可能是文字表达能力不太好,写得很抽象,但其实想要表达的便是这里的意思,如果花心思去做出和现在很多轮子一模一样的东西,确实太浪费时间也没有必要,但只是做做 demo,从过程中去感受轮子之所以这样设计,也是能学到很多东西的,也或许能从中迸发一些新的灵感

June 3, 2025 · 🦉

睡后收入好重要

要把博客当成朋友圈还真是有一点门槛呢,每一篇都需要想一个标题才行 很早就想过了,要做出点什么东西来,让自己有些被动收入,哪怕不高,但睡着也能赚钱总是令人感到喜悦 感谢自己最近的努力吧,总算还是有一点小成果,可以每天请自己喝杯瑞幸了 鉴于作品比较特殊,而且还有很长的路要走,就不多作分享,只分享这种每天都有微小收入的喜悦

June 3, 2025 · 🦉

牢骚

坚持写作确实是很难的事情 还记得最早折腾自己的博客,还是在上大学的时候,那时充满了新鲜感,觉得什么都好有趣,研究了很多东西,也写了很多 写得多了,慢慢不知道该写些什么了,可能是被学业绊住了脚,也可能只是懒散了,博客也就慢慢不再更新 也不知道当时经历了些什么,不想让身边的人看到我的博客,可能是怕写的内容过于浅薄被朋友笑话吧,来来回回搬迁了好几次,真爱折腾 也许只是测试不同的部署方案呢,是吧,就像现在已经只需要写好文档提交到 Github, Action 就自动集成 Vercel 自动部署了,相比于最早期的全手动,确实现代了很多 也正是因为好几次的搬迁,很多以前的文章遗失在了历史尘埃中,或者能找到文字但是嵌入的图片也没有了,也就算了吧 前段时间看到一篇文章,讲写作其实是思考的过程,写,不应该是为了给谁看,而仅仅是因为在思考,我思故我写,给人看只是副产物罢了。截图分享到朋友圈表示了赞同,有朋友问起我的博客地址,才发现自己已经很久不思考啦 还好我仍然会对此感到焦虑,至少还没能心安理得地放下自己的脑子,那还是捡起来吧,应该不丢人的 最近又看到一篇以前的文章,讲虽然现在技术很发达,可是互联网却像封建时代,大的公司垄断了数据,用户只是生产数据的数字农奴,每天发朋友圈发帖子,其实是免费劳动给这些公司增加资产,深觉如此 是不是很傻,别人文章怎么写我就怎么信,都没点自己的思考 不过傻就傻吧,我又要开始发神经了,要守护好自己的一片地方,哪怕没人看呢,并不重要,我自己留下思考的痕迹就好了

June 3, 2025 · 🦉

net/http Transport

$ go version go version go1.20.5 darwin/arm64 DefaultTransport 看一下 DefaultTransport 的 RoundTrip 方法。 1// src/net/http/roundtrip.go#L8 2// RoundTrip implements the RoundTripper interface. 3// 4// For higher-level HTTP client support (such as handling of cookies 5// and redirects), see Get, Post, and the Client type. 6// 7// Like the RoundTripper interface, the error types returned 8// by RoundTrip are unspecified. 9func (t *Transport) RoundTrip(req *Request) (*Response, error) { 10 return t.roundTrip(req) 11} 12 13// src/net/http/transport.go#L510 14// roundTrip implements a RoundTripper over HTTP. 15func (t *Transport) roundTrip(req *Request) (*Response, error) { 16 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults) 17 ctx := req.Context() 18 trace := httptrace.ContextClientTrace(ctx) 19 20 if req.URL == nil { 21 req.closeBody() 22 return nil, errors.New("http: nil Request.URL") 23 } 24 if req.Header == nil { 25 req.closeBody() 26 return nil, errors.New("http: nil Request.Header") 27 } 28 scheme := req.URL.Scheme 29 isHTTP := scheme == "http" || scheme == "https" 30 if isHTTP { 31 for k, vv := range req.Header { 32 if !httpguts.ValidHeaderFieldName(k) { 33 req.closeBody() 34 return nil, fmt.Errorf("net/http: invalid header field name %q", k) 35 } 36 for _, v := range vv { 37 if !httpguts.ValidHeaderFieldValue(v) { 38 req.closeBody() 39 // Don't include the value in the error, because it may be sensitive. 40 return nil, fmt.Errorf("net/http: invalid header field value for %q", k) 41 } 42 } 43 } 44 } 45 46 origReq := req 47 cancelKey := cancelKey{origReq} 48 req = setupRewindBody(req) 49 50 if altRT := t.alternateRoundTripper(req); altRT != nil { 51 if resp, err := altRT.RoundTrip(req); err != ErrSkipAltProtocol { 52 return resp, err 53 } 54 var err error 55 req, err = rewindBody(req) 56 if err != nil { 57 return nil, err 58 } 59 } 60 if !isHTTP { 61 req.closeBody() 62 return nil, badStringError("unsupported protocol scheme", scheme) 63 } 64 if req.Method != "" && !validMethod(req.Method) { 65 req.closeBody() 66 return nil, fmt.Errorf("net/http: invalid method %q", req.Method) 67 } 68 if req.URL.Host == "" { 69 req.closeBody() 70 return nil, errors.New("http: no Host in request URL") 71 } 72 73 for { 74 select { 75 case <-ctx.Done(): 76 req.closeBody() 77 return nil, ctx.Err() 78 default: 79 } 80 81 // treq gets modified by roundTrip, so we need to recreate for each retry. 82 treq := &transportRequest{Request: req, trace: trace, cancelKey: cancelKey} 83 cm, err := t.connectMethodForRequest(treq) 84 if err != nil { 85 req.closeBody() 86 return nil, err 87 } 88 89 // Get the cached or newly-created connection to either the 90 // host (for http or https), the http proxy, or the http proxy 91 // pre-CONNECTed to https server. In any case, we'll be ready 92 // to send it requests. 93 pconn, err := t.getConn(treq, cm) 94 if err != nil { 95 t.setReqCanceler(cancelKey, nil) 96 req.closeBody() 97 return nil, err 98 } 99 100 var resp *Response 101 if pconn.alt != nil { 102 // HTTP/2 path. 103 t.setReqCanceler(cancelKey, nil) // not cancelable with CancelRequest 104 resp, err = pconn.alt.RoundTrip(req) 105 } else { 106 resp, err = pconn.roundTrip(treq) 107 } 108 if err == nil { 109 resp.Request = origReq 110 return resp, nil 111 } 112 113 // Failed. Clean up and determine whether to retry. 114 if http2isNoCachedConnError(err) { 115 if t.removeIdleConn(pconn) { 116 t.decConnsPerHost(pconn.cacheKey) 117 } 118 } else if !pconn.shouldRetryRequest(req, err) { 119 // Issue 16465: return underlying net.Conn.Read error from peek, 120 // as we've historically done. 121 if e, ok := err.(nothingWrittenError); ok { 122 err = e.error 123 } 124 if e, ok := err.(transportReadFromServerError); ok { 125 err = e.err 126 } 127 return nil, err 128 } 129 testHookRoundTripRetried() 130 131 // Rewind the body if we're able to. 132 req, err = rewindBody(req) 133 if err != nil { 134 return nil, err 135 } 136 } 137} 因为 RoundTripper 说明了请求的 URL 和 Header 必须初始化,所以一开始检查报错。再往后,如果 schema 是 http 的话,检查了一下 header 的键值对的非法字符。再往后,注意到有一个 setupRewindBody,是用于恢复请求 body 的 ...

August 29, 2023 · 🦉

net/http Client

$ go version go version go1.20.5 darwin/arm64 如果一个文件一个文件挨着看未免也太枯燥了,并且没有和实践结合,感觉看了也体会不深。这里从发起一个请求到最后收到应答的整个流程,跟随一个 http.Request 的生命周期去探索相关的源码。 http.Client 开始发请求之前先看一下 http.Client 结构体 1// src/net/http/client.go#L29 2// A Client is an HTTP client. Its zero value (DefaultClient) is a 3// usable client that uses DefaultTransport. 4// 5// The Client's Transport typically has internal state (cached TCP 6// connections), so Clients should be reused instead of created as 7// needed. Clients are safe for concurrent use by multiple goroutines. 8// 9// A Client is higher-level than a RoundTripper (such as Transport) 10// and additionally handles HTTP details such as cookies and 11// redirects. 12// 13// When following redirects, the Client will forward all headers set on the 14// initial Request except: 15// 16// • when forwarding sensitive headers like "Authorization", 17// "WWW-Authenticate", and "Cookie" to untrusted targets. 18// These headers will be ignored when following a redirect to a domain 19// that is not a subdomain match or exact match of the initial domain. 20// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com" 21// will forward the sensitive headers, but a redirect to "bar.com" will not. 22// 23// • when forwarding the "Cookie" header with a non-nil cookie Jar. 24// Since each redirect may mutate the state of the cookie jar, 25// a redirect may possibly alter a cookie set in the initial request. 26// When forwarding the "Cookie" header, any mutated cookies will be omitted, 27// with the expectation that the Jar will insert those mutated cookies 28// with the updated values (assuming the origin matches). 29// If Jar is nil, the initial cookies are forwarded without change. 30type Client struct { 31 // Transport specifies the mechanism by which individual 32 // HTTP requests are made. 33 // If nil, DefaultTransport is used. 34 Transport RoundTripper 35 36 // CheckRedirect specifies the policy for handling redirects. 37 // If CheckRedirect is not nil, the client calls it before 38 // following an HTTP redirect. The arguments req and via are 39 // the upcoming request and the requests made already, oldest 40 // first. If CheckRedirect returns an error, the Client's Get 41 // method returns both the previous Response (with its Body 42 // closed) and CheckRedirect's error (wrapped in a url.Error) 43 // instead of issuing the Request req. 44 // As a special case, if CheckRedirect returns ErrUseLastResponse, 45 // then the most recent response is returned with its body 46 // unclosed, along with a nil error. 47 // 48 // If CheckRedirect is nil, the Client uses its default policy, 49 // which is to stop after 10 consecutive requests. 50 CheckRedirect func(req *Request, via []*Request) error 51 52 // Jar specifies the cookie jar. 53 // 54 // The Jar is used to insert relevant cookies into every 55 // outbound Request and is updated with the cookie values 56 // of every inbound Response. The Jar is consulted for every 57 // redirect that the Client follows. 58 // 59 // If Jar is nil, cookies are only sent if they are explicitly 60 // set on the Request. 61 Jar CookieJar 62 63 // Timeout specifies a time limit for requests made by this 64 // Client. The timeout includes connection time, any 65 // redirects, and reading the response body. The timer remains 66 // running after Get, Head, Post, or Do return and will 67 // interrupt reading of the Response.Body. 68 // 69 // A Timeout of zero means no timeout. 70 // 71 // The Client cancels requests to the underlying Transport 72 // as if the Request's Context ended. 73 // 74 // For compatibility, the Client will also use the deprecated 75 // CancelRequest method on Transport if found. New 76 // RoundTripper implementations should use the Request's Context 77 // for cancellation instead of implementing CancelRequest. 78 Timeout time.Duration 79} 80 81// DefaultClient is the default Client and is used by Get, Head, and Post. 82var DefaultClient = &Client{} 83 84// RoundTripper is an interface representing the ability to execute a 85// single HTTP transaction, obtaining the Response for a given Request. 86// 87// A RoundTripper must be safe for concurrent use by multiple 88// goroutines. 89type RoundTripper interface { 90 // RoundTrip executes a single HTTP transaction, returning 91 // a Response for the provided Request. 92 // 93 // RoundTrip should not attempt to interpret the response. In 94 // particular, RoundTrip must return err == nil if it obtained 95 // a response, regardless of the response's HTTP status code. 96 // A non-nil err should be reserved for failure to obtain a 97 // response. Similarly, RoundTrip should not attempt to 98 // handle higher-level protocol details such as redirects, 99 // authentication, or cookies. 100 // 101 // RoundTrip should not modify the request, except for 102 // consuming and closing the Request's Body. RoundTrip may 103 // read fields of the request in a separate goroutine. Callers 104 // should not mutate or reuse the request until the Response's 105 // Body has been closed. 106 // 107 // RoundTrip must always close the body, including on errors, 108 // but depending on the implementation may do so in a separate 109 // goroutine even after RoundTrip returns. This means that 110 // callers wanting to reuse the body for subsequent requests 111 // must arrange to wait for the Close call before doing so. 112 // 113 // The Request's URL and Header fields must be initialized. 114 RoundTrip(*Request) (*Response, error) 115} 简单翻译一下注释。 ...

August 29, 2023 · 🦉