架构师面试题相关总结

近期在找工作面试中,期间有较好的和高频的问题我进行了整理。

PHP的生命周期

程序执行到末尾了触发shutdown

调用exit、die函数,触发shutdown

SAPI使用PHP可以和其它应用进行交互数据(redis/mysql等) <---> sapi <---> PHP SAPI生命周期结束时触发shutdown

shutdown就是PHP启动清理程序,释放资源

GO中协程调度机制

把调度的控制权掌握在自己手里,做出比操作系统更好的决策

三种线程模型

  • N: 1,多个用户态线程运行在一个OS线程上。可以快速上下文切换,但不能利用多核的优势
  • 1: 1,1个用户态线程运行在一个OS线程上。上下文切换慢,但是能利用多核优势
  • GO试图通过M: N的调度器去获取全部优势。在任意数目的OS线程上调用任意数目的goroutines。可以快速切换上下文,也可以利用多核

goroutine的调度是按照抢占式调度的,一个goruotine最多执行10ms就会换下一个,和目前主流操作系统的CPU调度类似,按照时间分片

进程,线程,协程比较

应用程序的启动实例,进程拥有代码和打开的文件资源、数据资源、独立的内存空间

线程从属于进程,是程序的实际执行者,一个进程至少包含一个主线程。线程拥有自己的栈空间,线程是为了利用操作系统的多核,但是上下文切换需要时间。还涉及到锁

协程是比线程更轻量级的存在,一个线程可以拥有多个协程,协程是用户态的,由程序所控制,开销可以做到比线程更少

php cli cgi fpm

cli:命令行接口,在终端下执行php命令或脚本

php-cgi:解析php脚本的程序,php-cgi是PHP官方的fastcgi实现

php-fpm( fastcgi process manager ):对 php-cgi进程的管理和调度工作的程序

影响tcp连接的backlog

backlog是一个连接队列,做缓冲用,会缓冲已完成/未完成3次握手阶段的连接

backlog太大会导致积压、太小又会溢出

设置Linux内核参数 /etc/sysctl.conf

select,poll,epoll

select

  • 时间复杂度O(n)
  • 有I/O事件发生了,它不只知道是哪些流,只能一个个进行轮询找出读写的流进行操作(除了读写的流还有缓存流等)
  • 处理的流越多时间越长
  • 内核需要将消息传递到用户空间,需要内核拷贝(没有使用零拷贝方式)

poll

  • 时间复杂度O(n)
  • 本质和select没有区别,只是poll没有最大连接数限制,poll是基于链表存储的
  • 内核需要将消息传递到用户空间,需要内核拷贝(没有使用零拷贝方式)

epoll

  • 时间复杂度O(1)
  • 可以认为是event poll,epoll会把哪个流发生了怎么样的I/O事件通知我们
  • 事件驱动,每个事件关联了fd,不会随着fd的增加效率下降,只有活跃的fd才会调用callback
  • 利用mmap文件映射内存,减少复制开销(mmap是零拷贝实现的方式之一)

这三个都是I/O多路复用模型中的实现方式(理解为I/O聚集到一起比较好理解)

产生的原因:加入我们有100w个I/O流,是不是要开启一百万个进程--处理这些I/O流?CPU这个时候会消耗多少,这种方式能优化的

所以提出了I/O多路复用模型,一个线程,通过记录I/O流的状态来管理多个I/O,提高服务器的吞吐能力

Socket tcp dup的区别

tcp、udp是传输层的协议,tcp运行字节流超过512字节,udp报文最大长度是512字节

tcp提供有保障的传输,如果超时没有收到接收端的确认,进行重新传输。牺牲了大量的系统资源开销保证可靠,速度慢,udp不提供保障、速度快

tcp提供了数据传输的流控,有一个缓冲区接管,是由滑动窗口实现的

udp是基于报文发送的,报文首部会记录数据长度,不同报文是可以区别隔离出来的。应用层不存在拆包和粘包的问题

tcp是基于字节流传输的,应用层和传输层数据交换的是大小不等的数据块,并不知道哪些数据和哪些数据块应该在一起,tcp存在拆包和粘包的问题

PHP的调用链路追踪非侵入式怎么做

API网关 加php扩展这种(hook捕获调用Redis、MySQL这种的log)

侵入业务就是base框架中去做记录,业务基于base框架

TCP中的TIME_WAIT

TIME_WAIT是为了保障数据的有效传输和异常做的处理,可靠实现TCP全双工连接的停止、等待老的报文数据过期

tcp三次握手、四次握手主要分为建立连接、主动关闭、被动关闭

how:通过ss命令(socket statistics)查看网络连接状态

当tcp在四次握手中连接主动关闭的时候,连接双方不再交互消息了。都会经过TIME_WAIT。意味着主动断开的一方(请求方或响应方)并不会立马释放该连接,默认会等待2min。高并发短连接请求下,请求后立刻主动关闭。如果并发量持续很高会导致部分客户端显示连接不上。

我们可以通过文件 /proc/sys/net/ipv4/tcp_fin_timeout进行修改TIME_WAIT的时间

TIME_WAIT期间会暂用资源不释放,导致其它想连接的无法连接。这个资源有本地端口、socket句柄

怎么解决TIME_WAIT??

怎么缓解、提高并发数,不能彻底根治

1、服务端调大文件句柄数、加大内存

2、客户端绑定多张网卡,客户端每次发起TCP连接都会选择一个空闲的本地端口,是独占的

3、把TIME_WAIT的过期时间调低

长连接和短连接的区别

短连接是建立连接、传输数据、用完马上关闭连接。对应的是socket连接传输完数据马上断开连接

长连接是建立连接、保持连接、传输数据...用完不会马上关闭连接。对应的是socket连接后不管是否使用完了都保持连接(一直不使用会有超时机制)

长连接用于点对点的通讯,连接数不能太多。太多会出现连接不上,比如端口都被占用了。
不需要每次都去创建连接,后续的操作可以使用之前创建好的。频繁的socket创建资源是一种浪费、而且时间较长。长连接需要客户端和服务端定期的进行keep alive

长连接是占用着资源不立刻释放,牺牲空间换时间。像web网站的http服务选择短连接,因为web的客户端并发会很高,短连接能用完就释放

Socket编程相关

socket是一个门面模式

是在应用层和传输层之间通讯的一个中间抽象层,它是一组接口。(应用层<---socket--->传输层的tcp/udp)

socket可以创建tcp连接,也可以创建udp连接。屏蔽了应用层直接操作tcp、udp的复杂性

DNS、HTTP都是应用层协议,HTTP通过socket使用传输层的TCP协议

DNS通过socket使用的传输层TCP/UDP协议

域名解析时使用UDP协议,因为传输的内容不超过512字节

区域传送时使用TCP,传输的数据量很多,执行频次不高

PHP和Go对比

类型:PHP是脚本语言不需要编译、go需要编译

性能:支持多线程,go的性能、并发、速度较好。php重视的是开发速度

部署:go部署需要的容器要少于php需要的容器,内存占用较少

包管理:govendor、glide composer

语法:go简洁灵活,强调组合。php内置函数多,方便编码

应用:go侧重容器/高性能/云计算。php侧重后台/网站

相关文章

感觉本篇文章不错,对你有收获?

¥我要小额赞助,鼓励作者写出更好的教程
80 160 120

作者:

  • 出处: https://www.mi360.cn/articles/182
  • 本文版权归作者,欢迎转载,但未经作者同意必须保留 此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

评论区

最新评论

扫码关注