<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Jobhunter on Sirius&#39; Blog</title>
    <link>https://sirius2alpha.github.io/categories/jobhunter/</link>
    <description>Recent content in Jobhunter on Sirius&#39; Blog</description>
    <image>
      <title>Sirius&#39; Blog</title>
      <url>https://sirius2alpha.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://sirius2alpha.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo -- 0.127.0</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 12 Jun 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://sirius2alpha.github.io/categories/jobhunter/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>golang八股文</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/go8/</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/go8/</guid>
      <description>Golang goroutine内存泄漏 slice导致
获取长字符串中的一段，导致字符串未释放；
获取长slice中的一段导致长slice未释放；
在长切片中新建sllice导致泄漏
channel导致
发送不接受，接收不发送，nil channel
从 channel 里读，但是同时没有写入操作 向 无缓冲 channel 里写，但是同时没有读操作 向已满的 有缓冲 channel 里写，但是同时没有读操作 select操作在所有case上都阻塞() goroutine进入死循环，一直结束不了 向 nil channel 发送和接收数据都将会导致阻塞。这种情况可能在我们定义 channel 时忘记初始化的时候发生。 可见，很多都是因为channel使用不当造成阻塞，从而导致goroutine也一直阻塞无法退出导致的。
传统同步方式sync.mutex，sync.waitgroup导致
用了mutex加lock之后忘记unlock；
在一开始设置了具体数目的wg.wait(n)，但是有没有写够足够数量n的wg.Done()，导致wg.Wait()一直等待下去。（正确方式可以使用wg.Add(1)配合wg.Done使用）
Go调度器的GMP 在Go语言中，GPM通常指的是Goroutine、Processor和Machine，这是Go调度器（scheduler）的核心组成部分。下面是对每个部分的详细介绍：
Goroutine (G):
Goroutine是Go语言中的轻量级线程，由Go运行时管理。它们是并发的基本单位，可以被创建和销毁，而无需操作系统级别的线程开销。Goroutine的创建和销毁非常快速，因此可以轻松地创建成千上万个Goroutine。 Goroutine的调度是协作式的，这意味着一个Goroutine在执行时会自愿放弃CPU，让其他Goroutine有机会执行。这种协作式调度使得Go语言能够高效地利用多核处理器。 Processor (P):
Processor是Go调度器中的一个抽象概念，代表一个逻辑处理器。每个P都有一个本地运行队列，用于存储待执行的Goroutine。P的数量可以通过环境变量或运行时设置来调整，通常设置为CPU的核心数。 P的主要作用是管理Goroutine的执行。当一个Goroutine被调度到P上时，P会将其分配给一个可用的Machine（M）来执行。 Machine (M):
Machine代表一个操作系统线程。M与P关联，负责执行Goroutine。一个M可以与多个P关联，但在任何给定时间，一个M只能执行一个P的Goroutine。 M的主要作用是执行Goroutine的代码。当一个Goroutine被调度到M上时，M会执行该Goroutine的代码，直到该Goroutine自愿放弃CPU或被抢占。 Go调度器的工作原理是将Goroutine（G）分配到Processor（P）上，然后由Machine（M）执行。这种设计使得Go语言能够高效地利用多核处理器，并实现高并发。
在 Go 语言的运行时系统中，Goroutine（简称 G）有多种状态，用于描述它在不同时间点的执行情况。这些状态在 Go 的调度器（GMP 模型）中扮演重要角色。GMP 模型由 Goroutine（G）、工作线程（M）和处理器（P）三部分组成。以下是 G 的主要状态及其转变过程，以及它们与 GMP 模型的关系。
G 的状态 _Gidle：空闲状态。Goroutine 尚未被使用或已经完成执行，等待被分配新任务。 _Grunnable：可运行状态。Goroutine 已经准备好运行，等待被调度器选中运行。 _Grunning：运行状态。Goroutine 正在运行中。 _Gsyscall：系统调用状态。Goroutine 正在执行系统调用，处于阻塞状态，不会被调度器调度。 _Gwaiting：等待状态。Goroutine 在等待某个条件（例如通道操作、定时器、网络 I/O 等）完成。 _Gdead：死亡状态。Goroutine 已经完成执行，无法再被重新使用。 _Gcopystack：堆栈复制状态。Goroutine 的堆栈正在被复制，以调整其大小。 状态转变及其与 GMP 的关系 创建 Goroutine _Gidle -&amp;gt; _Grunnable 创建一个新的 Goroutine，并将其状态设置为 _Grunnable，表示该 Goroutine 准备好运行。 由 P 将新的 Goroutine 添加到其本地运行队列或全局运行队列中。 g := newGoroutine() g.</description>
    </item>
    <item>
      <title>system-design-prime</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/system-design-prime/</link>
      <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/system-design-prime/</guid>
      <description>system-design-prime 可用性模式 有两种支持高可用性的模式: 故障切换（fail-over）和复制（replication）。
故障切换 工作到备用切换（Active-passive） 关于工作到备用的故障切换流程是，工作服务器发送周期信号给待机中的备用服务器。如果周期信号中断，备用服务器切换成工作服务器的 IP 地址并恢复服务。
宕机时间取决于备用服务器处于“热”待机状态还是需要从“冷”待机状态进行启动。只有工作服务器处理流量。
工作到备用的故障切换也被称为主从切换。
双工作切换（Active-active） 在双工作切换中，双方都在管控流量，在它们之间分散负载。
如果是外网服务器，DNS 将需要对两方都了解。如果是内网服务器，应用程序逻辑将需要对两方都了解。
双工作切换也可以称为主主切换。
缺陷：故障切换 故障切换需要添加额外硬件并增加复杂性。 如果新写入数据在能被复制到备用系统之前，工作系统出现了故障，则有可能会丢失数据。 复制 主─从复制和主─主复制 这个主题进一步探讨了数据库部分:
主─从复制 主─主复制 CDN 内容分发网络 内容分发网络 CDN（英语：Content Delivery Network或Content Distribution Network）是一个全球性的代理服务器分布式网络，它从靠近用户的位置提供内容。通常，HTML/CSS/JS，图片和视频等静态内容由 CDN 提供，虽然亚马逊 CloudFront 等也支持动态内容。CDN 的 DNS 解析会告知客户端连接哪台服务器。
CDN 的分类 Pull CDN 当用户第一次访问CDN的时候，CDN上是没有资源的，这时候CDN会去向服务器拉取资源。之后的访问就直接在CDN服务器中返回就可以。
push CDN 服务器可以在用户访问资源之前，把资源push给CDN服务器。
如何选择哪种CDN？ 关于使用哪种 CDN 类型的决定在很大程度上取决于流量和下载量。从长远来看，托管视频和播客（又名大量下载）的旅游博客会发现推送 CDN 更便宜、更高效，因为在您主动将其推送到 CDN 之前，CDN 不会重新下载内容。拉式 CDN 可以通过在 CDN 服务器上保留最受欢迎的内容来帮助高流量小下载的网站。内容的后续更新（或“拉取”）频率不足以使成本超过推送 CDN 的成本。
LoadBlancer 负载均衡器 负载均衡器将传入的请求分发到应用服务器和数据库等计算资源。无论哪种情况，负载均衡器将从计算资源来的响应返回给恰当的客户端。负载均衡器的效用在于:
防止请求进入不好的服务器 防止资源过载 帮助消除单一的故障点 通常会设置采用工作─备用 或 双工作 模式的多个负载均衡器，以免发生故障。</description>
    </item>
    <item>
      <title>计算机基础知识</title>
      <link>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/cs-basic-notes/</link>
      <pubDate>Fri, 10 May 2024 00:00:00 +0000</pubDate>
      <guid>https://sirius2alpha.github.io/posts/notes/4-archive/%E6%B1%82%E8%81%8C%E5%BD%92%E6%A1%A3/cs-basic-notes/</guid>
      <description>计算机网络 TCP TCP为什么要进行三次握手？ 三次握手是建立网络连接的过程，确保双方能够正确地进行数据传输。
第一次握手SYN：客户端向服务端发送SYN请求同步信号，并初始化客户端序列号；
第二次握手SYN+ACK：服务端收到了客户端发送的SYN信号后回复ACK确认收到，同时也发送SYN，指定自己的初始序列号；
第三次握手ACK：客户端收到服务端的ACK+SYN后，回复一个ACK，表示已经收到服务端的ACK+SYN。这个包的序列会加一，表示客户端已经准备好和服务端进行数据传输了。
为什么是三次握手？不是两次或者四次 原因1：阻止重复的历史连接初始化
如果是两次握手的话，因网络堵塞的问题，客户端发送了两次SYN给服务端，服务端收到了第一个SYN的时候，就回复SYN+ACK给客户端，并进入了ESTABLISHED状态。而客户端这边收到了服务端旧的ACK+SYN，会认为这是历史连接从而发送RST报文，使服务端断开连接。
原因2：同步双方的序列号
TCP协议的双方都必须要维护一个序列号。两次握手只能保证一方的序列号被接收。
原因3：避免资源浪费
如果是两次握手，那么服务端在收到SYN后回复ACK的时候就要主动建立连接，要是网络堵塞，对面发了好多个SYN来，那完蛋了，建立了好多个TCP连接，造成了资源浪费。
TCP的四次挥手 四次挥手是指在TCP断开连接的过程中发生的，一般是由客户端发起，服务端完成最后的断开。
因为TCP是全双工通信，所以需要两边都要通知对方停止数据传输，故需要四次挥手保证断开连接。
具体流程：（刚开始双方都处于ESTABLISHED状态）
1.客户端向服务端发起FIN报文，表示客户端不再发送数据；（客户端进入FIN_WAIT_1中状态）
2.服务端收到FIN报文后，回复一个ACK表示收到；（服务端进入CLOSED_WAIT状态，客户端收到ACK后进入FIN_WAIT_2状态）
3.服务端向客户端发起FIIN报文，表示服务端也不再发送数据；（服务端进入LAST_ACK状态）
4.客户端收到服务端的FIN报文后，也回复一个ACK。（客户端进入TIME_WAIT状态）
发送端在最后会进入到TIME_WAIT的状态，
为什么有TIME_WAIT状态？ 原因1：保证历史连接中的数据不会干扰下一次连接。
原因2：保证被动关闭连接。如果服务端没有TIME_WAIT状态直接close的话，要是服务端没有收到客户端最后一次发送的ACK会重发FIN，如果服务器已经处于CLOSE状态，就会返回RST报文，RST报文会被服务端认定为错误。
为什么TIME_WAIT的时间是2MSL？ MSL是报文的最大生存时间，超过这个时间的报文都会被丢弃。两个MSL时间可以保证客户端发送的ACK报文可以到达服务端+服务端要是在第一个MSL中没有收到ACK可以重发一次FIN到客户端，并保证能够到达客户端。
HTTP GET方法和POST方法有什么区别？ 用途：GET方法一般用于请求服务器上的数据；POST方法用于向服务器提交数据。
请求参数：GET方法的请求参数一般放在URL中，POST的请求参数一般放在请求体中。
幂等：多次执行相同的操作，结果都相同。
幂等行：GET方法是安全幂等的，POST不是幂等的。
缓存机制：GET请求会被浏览器主动cache，如果下一次传输的数据相同，就会返回浏览器中的内容；而POST不会。
GET的请求参数会被保存在浏览器的历史记录中，而POST中的参数不会保留
时间消耗：GET产生一个TCP数据包，浏览器会把header和data一起发送出去，服务器相应200；
POST产生两个TCP数据包，浏览器先发送hader，服务器相应100（继续发送），浏览器再发送data，服务器相应200
什么情况下会使用POST读取数据？ 当查询的数据量很多，GET方式的URL太长太大，GET方式大概是4KB，POST上限是8MB 当对数据的安全性有更高要求的时候，可以在POST的请求体中对数据进行加密 HTTP版本对比 HTTP/0.9 只支持GET方法 HTTP/1.0 支持多种请求方式 引入了请求头和响应头 引入状态码 不支持长连接
HTTP/1.1 支持长连接 管道网络传输（可以同时发送A、B请求，不必等待A响应） 但是管道网络传输存在队头阻塞的问题
头部冗余
没有请求优先级
请求只能通过客户端推送，服务器不能主动推送
HTTP/2 使用HPACK进行头部压缩 把数据部分压缩成头信息帧和数据帧 并发传输：引入了stream的概念，多个Stream复用一条TCP连接，通过streamID识别，不同stream的帧可以乱序发送 支持服务器推送 HTTPS 和HTTP对比 优点
安全性更高
缺点
HTTPS涉及到了加解密的过程，所以对服务器的负荷会高一些；
握手阶段的延迟比较高，因为还有SSL/TLS握手;
加密过程 HTTPS采用了对称加密+非对称加密的混合加密模式</description>
    </item>
  </channel>
</rss>
