面试得越多 心里越踏实

81 阅读7分钟

复盘

今天面试面试官基本上没问多少问题 就简单介绍了一下之前的项目 大部分都是让我自己说 感觉怪怪的 好像并不想面试我 问了问题也没有下文 就是我自己背八股文

讲一下用go遇到的问题

  • 一时没想到什么说的 语言本身的问题我还没怎么遇到过 遇到的问题也都是自己技术不精 跟语言无关

说一下http协议

超文本传输协议

http/1.1 相比1.0

  • 使用了长连接 实际上就是默认开启了http keep live
  • 开启了管道的模式 不必等待前面请求的返回 可以连续发送请求

但 HTTP/1.1 还是有性能瓶颈:

  • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
  • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
  • 没有请求优先级控制;
  • 请求只能从客户端开始,服务器只能被动响应。

HTTP/2

  • 头部压缩
  • 如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
  • 二进制格式
  • HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)
  • 并发传输
  • HTTP/1.1 的实现是基于请求-响应模型的。同一个连接中,HTTP 完成一个事务(请求与响应),才能处理下一个事务,也就是说在发出请求等待响应的过程中,是没办法做其他事情的,如果响应迟迟不来,那么后续的请求是无法发送的,也造成了队头阻塞的问题。 而 HTTP/2 就很牛逼了,引出了 Stream 概念,多个 Stream 复用在一条 TCP 连接。
  • 服务器主动推送资源

有一组扑克 不借助额外的空间 怎么最快的将这堆扑克打乱

  • 本来我的回答是借助两个数组 面试官让不借助额外的空间 那么就遍历一遍数组 每个元素和未交换过的区域内的元素随机交换

GMP模型

  • G是协程队列 M绑定一个线程 P是调度器
  1. 核心的操作系统线程(M)不能够无P的情况下执行G。
  2. P的数量通常取决于机器上的CPU核心数。在程序启动时,Go运行时会根据GOMAXPROCS环境变量或者是使用runtime.GOMAXPROCS()来设定P的数量。
  3. 每个P都有一个与之关联的本地G队列,新的Goroutine在创建时首先会在当前P的本地G队列中加入。
  4. 当一个M在其本地P队列上没有找到可以执行的G时,它会尝试从其他P的队列中窃取G。

限流 熔断

  • 限流就是对微服务的访问或调用进行限制,防止过多的请求一次性发送到微服务上而导致它崩溃。限流的方法有很多种,如固定窗口、滑动窗口、令牌桶、漏桶等。限流可以通过一些开源的中间件实现,例如Nginx、Sentinel等。 根据限流的级别,它可分为全局限流和局部限流。全局限流主要是对整个系统做流量控制,而局部限流则是更加细粒度的控制,例如,针对某一个用户、针对某一个API等。
  • 熔断器模式是一种自动的保护机制,当微服务无法处理请求或反应慢的时候,熔断器会自动打开,阻止更多的调用,防止系统有雪崩效应。 熔断器通常有三种状态:关闭、开启、半开。一开始熔断器是关闭的,如果失败的请求达到一定阈值,就会打开熔断器,所有的请求都无法到达目标服务。一段时间后,熔断器会进入半开状态,尝试放行部分请求去检测服务的状态,如果服务恢复了,熔断器就关闭,否则就会重置熔断的时间,再次短暂地阻碍全部请求。常用的熔断中间件包括Hystrix,Resilience4j等。
  • 总的来说,限流是为了对资源进行保护,防止因为过多请求而导致服务失败。而熔断则是为了在服务已经开始出现问题时,防止错误的进一步扩散。因此,这两种措施在微服务环境下极其重要。

热更新

  • 因为是面试的游戏公司 所以我只能按照以前做游戏的思路勉强回答了一下 如果是功能的热更新 只能是通过动态加载脚本 如果是配置类的热更新 那么可以做热读配置

二面

说是阿里出来的大佬 感觉水平挺高的

用socket实现获取百度网页代码

  • 上来直接给我干懵了 估计是想考察我对socket编程的熟练度和对http协议的熟悉程度

有一张表 存有坐标信息 其中lat0 lon0 两个字段都是浮点数 怎么设计索引 用sql语句怎么查询离x(21,22)最近的坐标 前10条记录

  • 这个没答好 一下给忘了 两点之间计算距离的公式 只想到了redis的GEO 可以先把坐标转换为geohash 按照这个值索引

如果不用dtm 自己打算怎么处理分布式事务

  • 我说的用消息队列去通知各个服务 然后处理完成之后又回调业务发起方

找最小组合数

  • 动态规划

介绍一下https 建立连接的流程

  1. 客户端发起HTTPS请求:当你在浏览器中输入一个HTTPS网址时,浏览器会先连接服务器的443端口(默认的HTTPS端口)。
  2. TCP握手:客户端和服务器会进行三次握手来建立一个TCP连接。
  3. 客户端Hello:
    客户端发起客户端Hello消息给服务器,消息中包含:客户端支持的协议版本,比如TLS 1.0版;一个客户端生成的随机数(Client Random);客户端支持的加密算法,比如RSA公钥加密、AES对称加密等;其他一些网络通讯相关的参数。
  4. 服务器Hello:
    服务器收到客户端的Hello消息后,会选择客户端提供的参数(比如选择一个加密算法,以及此次会话所支持的TLS协议的版本等)作为会话参数,并生成一个随机数(Server Random),然后服务器把这些参数连同自己的证书一起打包成一个服务器Hello消息回传给客户端。
  5. 服务器证书验证:
    客户端收到服务器Hello消息后,开始验证证书的合法性。包括:证书的有效期、签发者公钥、证书持有者是否为当前网站等。
  6. 密钥交换:
    如果服务器证书验证没有问题,客户端会生成一个新的随机数(Premaster Secret),并用服务器的公钥对这个随机数进行加密,然后传输给服务器。服务器用自己的私钥进行解密得到这个新的随机数。接下来,客户端和服务器就可以使用三个随机数(Client Random, Server Random, Premaster Secret)推导出同一套加密/解密参数。
  7. 客户端传输“Client Finished”消息:
    客户端传输一个“Client Finished”消息给服务器,这个消息会通过之前生成的参数进行加密。
  8. 服务器传输“Server Finished”消息:
    服务器收到“Client Finished”消息,解密验明无误,并通过同一套参数加密传输“Server Finished”消息给客户端。
  9. 握手结束:
    客户端接收并解密“Server Finished”消息,证明握手过程正常结束,客户端和服务器之间以后的通讯都会通过之前的密钥进行加密