Go面试看这里了~(十七)

161 篇文章 12 订阅

原文地址:Go面试看这里了~(十七)

1、time-wait?

TIME_WAIT是TCP协议中断开连接所经历的一种状态,状态图如下:

上图中作为主动关闭的一方(Client)出现了TIME_WAIT状态,目的是告诉Server端,己方没有需发送的数据,但是仍然保持了接收对方数据的能力。

常见关闭连接过程如下:

  1. 当客户端无待发送数据时,会向服务端发送FIN消息,发送消息后进入FIN_WAIT_1状态。

  2. 服务端接收到客户端的FIN消息后,进入CLOSE_WAIT状态并向客户端发送ACK消息,客户端接收到ACK消息时进入FIN_WAIT_2状态。

  3. 当服务端无待发送数据时,服务端会向客户端发送FIN消息。

  4. 客户端接收到FIN消息后,进入TIME_WAIT状态并向服务端发送ACK消息,服务端收到后进入CLOSED状态。

  5. 客户端等待两个最大数据段生命周期(Maximum segment lifetime,MSL)的时间后也进入CLOSED状态。

TIME_WAIT一定是发生在主动关闭一方,被动关闭一方会直接进入CLOSED状态,主动关闭一方需要等待2*MSL时间才会最终关闭,客户端和服务端之间的连接此时就会正常关闭,新创建的TCP连接收到影响的概率也微乎其微,保证了数据传输的可靠性。

TIME_WAIT主要为防止被动关闭方的延迟数据被窃取,及未收到最后的ACK报文。

Redis在并发量突增时很容易出现TCP连接失败(无可用端口),原因在于TIME_WAIT数量过大(会占用端口),每次连接断开后都会产生TIME_WAIT,跟三次握手四次挥手有关,其实本质上TIME_WAIT是用于优化网络通信的,如关闭此优化方案,虽然可行,但不建议这样处理,关闭之后可能会产生其它网络异常,虽然可能是小概率的,这里提供几条优化建议:

  1. 对于Redis缓存,使用redisgo自带的连接池,需配置MaxIdle值。

  2. 对于数据库,自带连接池(默认可能未启用),直接调用SetMaxIdleConns设置MaxIdle值。

  3. 对于http请求,默认没有连接池,可使用通用的go-commons-pool,通过borrow和return机制使用连接池,如有资源申请要记得释放。

  4. 通过nginx转发,需在nginx.conf配置文件中增加keep-alive配置。

2、for循环遍历slice的问题?

  1. 子切片和父切片用的是同一个底层数组,改变子切片的值,也会改动到父切片。

  2. for range遍历的是副本,对副本的改动不会体现在原有切片。

  3. for循环中直接出来的值永远是遍历的最后一位,需定义局部变量。

3、现有100枚硬币,其中有一枚硬币重量不一样,用天平秤怎么快速找到这一枚硬币?

第一次:将100枚硬币分两份,每份50,选择重量较轻的一组继续称。

第二次:将50枚硬币分两份,每份25,选择重量较轻的一组继续称。

第三次:取出1枚硬币,将剩下的24枚硬币分两份,每份12枚硬币,如重量一致,则取出的那1枚硬币就是假币,反之选择重量较轻的一组继续称。

第四次:将12枚硬币分两份,每份6,选择重量较轻的一组继续称。

第五次:将6枚硬币分两份,每份3,选择重量较轻的一组继续称。

第六次:取出1枚硬币,将剩下的2枚硬币分两份,每份1枚硬币,如重量一致,则取出的那1枚硬币就是假币,反之较轻的那枚硬币为假币。

至此,本次分享就结束了,后期会慢慢补充。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

扫码关注公众号,获取更多优质内容。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值