1.Linux系统
1.Linux常用命令
- 基本命令: cd/ ls/ pwd/ mkdir/ cat/ tac/ touch/ cp/ mv/ rm/ less/ head/ tail/ echo/ grep/ su/ where/ systemct
- 用户管理: useradd/ passwd/ usermod/ userdel/ change
- 组管理: groupadd/ groupdel/ gpasswd
- 压缩解压缩: zip/ gzip/ bzip/ xz
- 权限管理: chmod/ chown/
- 端口占用 lsof -i:5000
- 查看大于多少的文件 find /opt -type f -size +500M -print0 | xarg -0 ls -lh | sort -nr
- ls -l /etc > /home/myback.txt (覆盖重定向)把显示的结果覆盖到/home/myback.txt中去
- ls -l /etc >> /home/myback.txt (追加重定向)把显示的结果追加到/home/myback.txt中去
2.系统性能信息查看命令
- top:相当于windows任务管理器,可以监控CPU/内存使用情况,每个任务占用的CPU/内存
- netstat -nalp:监听端口/网络统计信息
- free -m: 查看内存使用情况
- df -lh: 查看对应磁盘使用情况
- du -sh *: 如果想查看当前目录下的所有文件各个大小
- vmstat:虚拟内存统计,显示CPU/内存/硬盘/系统进程/IO模块
- uptime:运行时间/显示当前用户数/cpu负载状况(不能超过CPU个数,任务阻塞,尽量少于70%)可以用lscpu来查看一共有几核
- tcpdump:网络抓包工具,可以通过添加v的个数来获得更具体的TCP/UCP请求记录
- ps/ptree:运行进程的快照和树状图
- firewalld: systemctl start/status/stop firewalld
- iptables:对服务器进行网络访问控制,过滤/修改/高级修改 IP/协议/接口/端口号/连接状态,通过netfilter模块实现
- ping/nslookup
3.开机启动过程
- 加电BIOS(basic I/O system),POST(power on self test)
- 读取第一扇区MBR的引导文件,交给Grub2引导
- Grub2定位和加载内核到内存
- 内核控制,自解压,运行systemd(原来是init,PID 1)
- 运行响应级别/target
- 运行终端,输入账号密码登录
4.run level各个级别的意思
0 -> 关机, 1 -> 单用户模式(类似windows安全模式), 2 -> 不包含NFS的命令行模式,3 -> 完整命令行模式, 4 -> 系统保留,5 -> 图形模式,6 -> 重启
- runlevel:查看当前runlevel
- init:切换当前runlevel
- 现在runlevel已经被target的概念取代
5.硬链接和软链接区别
硬链接的inode相同,指向硬盘中同一块物理地址,而软链接是保存了被复制文件的绝对路径,当访问软链接的时候会自动把路径替换成所指路径。
6.shell脚本对于日志文件获取有用信息的处理
2.网络
TCP/UDP相关:
1. TCP/UDP区别
- TCP:面向连接,可靠,速度慢,效率低
- UDP:无链接,不可靠,速度高,效率高
2.tcp保证可靠的传输机制
- 效验和,通过hash值确定字段正确
- 序列号,保证传输顺序和去重
- 三次握手确定连接成功
- 超时重传
- 滑动窗口/满启动,防止丢包
- 四次挥手确保传输完成
3.拥塞控制的四种算法
- 慢启动:从1开始指数增长
- 拥塞避免:超出窗口以后,减半并开始线性增长
- 快重传:接收方收到失序请求(M3丢失)后返回M2确认
- 块恢复:发送方接收到三次M2以后流量减半,重新线性增长
4.三次握手四次挥手,以及其中各个状态的转换
三次握手:SYN -> ACK/SYN -> ACK 四次挥手:FIN -> ACK -> FIN -> ACK 每次回复ACK的时候会在序列号上加1返回
5.为什么是三次和四次
三次握手:(确定双方收发能力,防止空连接)
- SYN:服务器知道自己可以接收/客户端可以发送
- ACK/SYN:客户端知道双方都可以收/发
- ACK:服务器端知道双方可以收/发,并且可以避免空连接 四次挥手: TCP是双向对等传输,必须双方都确认FIN才能结束,客户端发送FIN信号以后关闭了发送通道,但是仍需要保持接收通道开启直到服务器端返回FIN,并且返回ACK告知自己已经关闭。
6.SYN flood攻击及解决办法
一个处于Listening状态的TCP端口会为每一个SYN请求分配TCB(Transmission Cotrol Block)。如果恶意向服务器发送大量SYN,服务器端会因为开启大量TCB而耗尽资源。 解决方法:
-
- 无效连接的监视释放:监视半开连接,达到阀值后无差别释放所有半开连接资源,会误释放掉正常请求。
-
- 延缓TCB分配方法:SYN flood很难建立起正常连接,可以在真正建立起连接后再分配TCB。有两种方法:Syn Cache技术会保存序列号,而Syn Cookie不使用任何资源用算法生成序列号。
-
- 使用SYN防火墙
7.Time_wait等待的意义
客户端在四次挥手的最后一次ACK以后不能确定服务器端是否收到了ACK信号,这种时候有两种情况:
-
- 服务器端没有收到,会超时重传FIN
-
- 服务器端收到ACK,不会发任何消息 这时候time_wait会等待2MSL(Maximum Segment Life)的时间来确认是否需要重传(ACK的MSL+FIN的MSL),如果不等的话服务器端口可能还没关闭,会造成数据冲突。
8.回退N帧协议
滑动窗口和合并确认,每次发送M个数据包,接收方返回序列号N代表N之前的数据都有序接收成功,发送方需要重新发送N+1到M之间的数据包。
HTTP相关:
1.常见状态码
- 200 请求成功
- 301 永久重定向
- 302 临时重定向
- 304 未修改,可以从浏览器缓存读取
- 400 Request语法错误
- 401 未授权
- 403 拒绝提供服务
- 404 无法找到请求资源
- 500 服务器内部错误
- 503 服务器宕机
2.长连接/短连接
HTTP1.0默认短连接,HTTP1.1默认长连接。比如当一个网页打开后传输数据的TCP连接不会断开,只会在设定的过期时间断开,需要在响应头加入Connection:keep-alive.
3.Get和Post的区别 (例子:POST下单后返回receipt)
- GET可以被收藏,POST不可以
- GET会被保存在历史记录,POST不会
- GET有长度限制,POST没有
- GET直接暴露在url上,POST的参数在request body里,相对安全
4.HTTP2/HTTP1区别
- 1.二进制:原来是文本格式,二进制更高效,更准确
- 2.多路传输:传输更高效
- 3.报头压缩:由于TCP的三次握手,和数据分装报头开销很大
- 4.服务器推送:服务器可以分析浏览器的需求直接推送资源,减少延迟
5.格式
请求行(1) + 请求头(2 + 3) + 请求数据
DNS常见:
1.DNS解析过程
查看浏览器缓存->查看本机缓存->查看本地DNS服务器->顶级域名服务器->查看根域名服务器... 依次向上逐层寻找
2.DNS中的字段/记录
要管理一个DNS记录,添加的时候需要三个字段:主机名/托管IP地址/TTL(过期时间)
3.如果DNS解析出现错误,解决的思路是什么?DNS的工作原理是什么?
DNS是一个大型的DFS,每个域都需要一组授权名称服务器,如果解析错误可能是名称服务器出错,可以配置更换授权域名服务器。 1.nslookup查看DNS是否真的故障 2.清除DNS缓存(本地缓存过期) 3.更换授权名称服务器(服务器宕机)
常见其他问题:
1.Ping和traceroute的工作原理
ping命令使用ICMP协议,用来测试两台主机之间的连通性。traceroute命令也是基于ICMP来获取连接路径的所有路由器。
2.路由和交换机的区别
交换机是在数据链路层基于MAC地址来转发数据,路由是网络层基于IP地址来转发数据
3.输入网址后,背后发生了什么?
-> 解析URL,生成HTTP报文 -> 递归逐层读取DNS缓存,解析成IP地址,并动态寻找最快路由路径 -> 进行ARP解析,通过IP地址和子网掩码解析出ARP -> 进行三次握手 -> Nginx反向代理接受到请求 -> 向CDN请求静态资源 -> 将动态资源请求分发到Tomcat/Apache -> 去redis/Mysql中请求资源并逐层返回 -> 浏览器接收到静态文件以后进行渲染
3.操作系统
1. 进程和线程的区别:
根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。
包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
进程优点:每个进程有互相独立的地址空间,不影响主程序的稳定性,子进程崩溃没关系; 缺点:需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算 多进程调度开销比较大。
线程优点:无需跨进程边界; 缺点:每个线程与主程序共用地址空间,受限于2GB地址空间;
2. 进程的切换方式?在进程处于就绪态时还会有发生哪些事情?进程的状态(new/running/ready/blocked/exit)
- 运行态—→等待态:等待使用资源;如等待外设传输;等待人工干预。
- 等待态—→就绪态:资源得到满足;如外设传输结束;人工干预完成。
- 运行态—→就绪态:运行时间片到;出现有更高优先权进程。
- 就绪态—→运行态:CPU 空闲时选择一个就绪进程。
3. 线程与线程同步的方式有哪些
- synchronized同步方法或者代码块
- volatile关键字,免锁,每次都会重新计算而不是使用寄存器中的值
- lock/unlock上锁reentranlock
- 悲观锁(适合写多读少):认为别人会修改数据,先加锁独占数据,比如synchronized/reentranLock,数据库的行锁/表锁
- 乐观锁(适合读多写少):认为没人会修改数据,在更新数据的时候会检测有没有其他线程使用该数据,java通过CAS(compare and swap)实现,数据库的write_condition
4. 进程的通信方式有哪些
- 1.管道pipe:速度慢,容量有限,只有父子进程能通讯
- 2.命名管道FIFO:任何进程间都能通讯,但速度慢
- 3.消息队列MessageQueue:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
- 4.信号量:不能传递复杂消息,只能用来同步
- 5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全。
5. 操作系统的常见进程调度算法
- FSFS
- 短作业
- 优先级
- 动态优先级
- 时间片轮转法
6. 死锁的四个条件,解决与避免的方法
- 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
- 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
- 环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。 解决方法: 资源一次性分配/资源按顺序分配/优先级机制/无法获取全部就剥夺当前资源
7. IO模型以及同步异步阻塞非阻塞的区别
出于安全考虑,进程不能直接操作I/O,需要向内核发送请求协助工作,Kernel会先从IO获取数据存在Kernel buffer然后再把数据拷贝到地址空间。
- 阻塞I/O(blocking I/O)准备/复制
- 非阻塞I/O(nonblocking I/O)复制,但是CPU消耗高
- I/O复用(select和poll) (I/O multiplexing)准备和复制独立阻塞
- 信号驱动I/O(signal driven I/O (SIGIO))收到回调开始复制
- 异步I/O (asynchronous I/O (the POSIX aio_functions))操作完成后通知 Tip:前四种都是同步,只有最后一种才是异步I/O。
8. 分页和分段有什么区别
分页是信息的物理单位,每个电脑固定,为了消减内存的碎片,一维地址空间,笔记本1页第一天,2页第二天。 分段是为了满足用户的需要,长度不固定,二位地址空间,笔记本1-30页数学,31-50页语文。
9. 数据从内存写到磁盘上发生的过程,具体行为是什么
调用API(write方法)->为了兼容不同文件系统调用VFS的sys_write->添加一个inode用于记录data文件->调用blockIO->在缓存队列等待合并操作
4.Python
1.深拷贝/浅拷贝/赋值
- 赋值只想当于一个别名,指向相同内存地址
- copy()只拷贝父级list里的元素,内部list仍然指向相同内存地址
- deepcopy()会递归遍历拷贝元素
2.闭包、装饰器
闭包:将函数作为返回值返回,通过闭包可以创建一些只有自己能访问的变量,可以私有化数据,保证数据安全
- 1.装饰器是基于闭包实现的
- 2.装饰器可以让函数在不需要做任何代码改动的情况下增加功能
- 3.装饰器的返回值也是一个函数的对象
3.迭代器、生成器
- 迭代器:正常list会直接把所有数据放进内存里,iter(list)迭代器只保存当前位置和结束为止,用next()方法获取下一位,占用内存少,在处理大型数据方面表现良好。
- 生成器:生成器使用yield函数,返回一个迭代器函数,每一次遇到yield会储存当前数据并暂停,在执行下一次yield方法时从当前位置继续运行
4.多线程
5.内存管理
- 1、大内存使用malloc进行分配
- 2、小内存(256KB)使用内存池进行分配
6.垃圾回收机制
(主)引用计数/(辅助)标记-清除,会阻塞+碎片/分代回收
- 调优:手动垃圾回收/避免循环引用/调高垃圾回收阀值
7.*args,**kwargs
5.mysql
1.基本sql语句
2.主从复制(架构/错误恢复/MHA)
主服务器的任何修改都会被保存在二进制日志log里,从服务器会定期复制日志log检查更新换代同步修改
3.mysql存储引擎
4.备份(热备/冷备)
跳板机
三个作用
- 操作系统权限集中管理(Linux多用户),每个用户只能控制自己能访问的服务器
- 网络安全访问限制,只保留一个外网(跳板机/负载均衡)入口,其他都形成局域网
- 记录管理人员的操作行为 日志行为|录屏
数据防泄漏
DSM文档(物流公司,对文档/源代码加密),DSA数据安全隔离(主要用于源代码防泄漏,在固定区域内只能进不能出),SDC沙盒隔离(相当于一个虚拟机),DLP数据防泄漏(会对文件进行检查,误报率较高)
海量数据处理
6.运维相关的 Docker 高可用。负载均衡 Nginx、lvs、keepalived、监控、cdn等很多,这些有擅长的点,也不用做到全会,视自己情况定。
CDN -> 并行防火墙(根绝对外IP计算出VIP) LVS -> Nginx七层负载 -> Nginx动静分离 tomcat -> redis/mysql/mongodb(zookeeper) 服务器之间通过MQ通信
6.面经
1. SLA & SLO是什么?
www.interviewbit.com/sre-intervi… 根据SLI来制定SLO,并和客户签署SLA。SLI包括down time, 延迟, 流量,错误率等。AWS就会定时的因为底层主机的更换或者维护而重启机器或者服务,但是这些是不违反SLA的。在签署SLA的时候要给自己留余地,比如能做到99.999%,但是签署99.9%。
2. 一个服务需要定义哪些指标来表示服务是健康的?如何设计监控系统
参数层面
- 从云平台&管理平台侧监控机器/容器状态
- 监控服务进程,端口是否正常运行
- 监控CPU,Memory,Disk等饱和度告警(添加持续时间&间隔时间来避免过多告警)
- 监控网络流量,延迟,错误码(监控日志)数量和比例
- 监控数据量是否有异常,元数据和入库数量对比
设计层面
- 添加持续时间&间隔时间来避免false alarm,尽量减少不必要告警
- 监控绝对值或者相对值
- 对告警定义不同等级,设置预警和警报等,不同等级的提醒程度不同
- 对关键服务节点设立日志和参数监控,利于分段调查
- 设立公共文件,标准化告警处理流程
技术层面
- log collector从机器采集数据
- prometheus对数据进行采集
- 在grafana上用query对数据进行可视化并配置告警
- 配置pagerduty才发送告警到手机
- Cloudwatch也可以进行告警配置
3. 有两个服务,服务A和服务B。服务A会调用服务B的接口。并且我们知道他们是用tcp连起来的。我们现在只知道服务A的地址,我们应该怎样找到服务B的地址,用什么命令
- 1.查看config文件或者code
- 2.查看服务器A上的log然后grep有用信息
- 3.netstat和nmap看A都和谁建立连接
4. 如何做release?如何保证release的可靠性?如果发现bug,如何进行修补?应该revert还是patch?如果bug是跟特定的region有关的,有没有什么办法快速恢复
如何做release?如何保证release的可靠性?
- 和Dev团队沟通好发布时间,发布流程,回滚计划,确定流量变化。确认不同地区的政策差别
- 在测试环境进行部署和监控,QA进行测试
- 备份老版本,确保出现问题可以快速回滚
- 设置好product环境告警,部署以后进行灰度阶段性发布,关注流量和告警
- 发布时把相关责任人拉群和warroom,确保发生问题第一时间修复
如果发现bug,如何进行修补?应该revert还是patch?
- 根据问题详细描述跟QA合作复现步骤,确认影响范围
- 把问题相关责任人拉群确认修复计划和时间表
- 如果bug较小则进行补丁发布/补偿发放
- 如果bug较大则可以先回滚到稳定版本在重新进行修复
如果bug是跟特定的region有关的,有没有什么办法快速恢复
- 如果考虑LB把流量打到附近负载低的服务器(Region-Failover)
- 暂时性降级,保证服务部分可用,降低服务器压力和影响范围
- 把特定地区进行回滚,并检查package版本、当地网络、CDN和整条链路
5. Linux信号是如何工作的?ctrl+c 发送的是啥信号?
- Ctrl+C比较暴力,就是发送Terminal到当前的程序SIGINT
- Ctrl+Z是把当前的程序挂起,暂停执行这个程序SIGHUP
- Ctrl+D 是发送一个EOF,不是信号
- 可以同kill -l查看所有信号 URL(统一资源定位符)的结构包括以下几个部分:
6. Describe the structure of the URL?
-
协议(Scheme): URL的第一部分是协议,它指定了访问资源时要使用的通信协议。常见的协议包括HTTP、HTTPS、FTP、SMTP等。例如,"https://"表示使用HTTPS协议。
-
域名(Host): 域名部分指定了资源所在的主机或服务器的地址。它可以是一个IP地址或一个可读性更好的域名,如"www.example.com"。
-
端口号(Port): 端口号是可选的,用于指定服务器上的特定服务。如果未指定端口号,默认使用协议的默认端口。例如,HTTP的默认端口是80,HTTPS的默认端口是443。如果需要指定不同的端口,可以在域名后使用冒号,如":8080"。
-
路径(Path): 路径部分指定了服务器上资源的具体位置。它以斜杠"/"开头,可以包含多级目录结构,用斜杠分隔。例如,"/products/electronics"表示访问位于"/products/electronics"路径下的资源。
-
查询字符串(Query): 查询字符串是可选的,用于传递参数给服务器。它以问号"?"开头,参数之间使用"&"分隔。例如,"?id=123&name=John"表示传递了两个参数,一个是"id",值为"123",另一个是"name",值为"John"。
-
片段标识符(Fragment): 片段标识符也是可选的,用于指定资源中的特定部分或锚点。它以井号"#"开头。例如,"#section2"表示跳转到资源中名为"section2"的部分。
URL的完整结构示例:
https://www.example.com:8080/products/electronics?id=123&name=John#section2
7. REST make request的时候有啥 header
- Authorization
- Content-Type
- Content-Length
- Cache-Control
- Cookie
- Accept
- Connection
- User-Agent
8. 排查oncall问题流程
- 确认告警等级,根据告警名大概定位问题
- 查阅文档,确认排查流程和相关责任人
- 排查CPU,内存,流量数据。调查相关错误码和日志
- 相关责任人拉群和warroom,分享现有信息
- 分段式定位问题位置,QA进行复现,分析是代码错误,配置问题,网络故障还是资源不足
- QA验证问题修复,关闭ticket
- 整理问题报告
9. 什么是Distributed System
资源扩展包括横向和纵向,分布式系统属于纵向扩展。多台服务器通过网络或者硬件通信来进行协作,从而共同完成某些服务,例如储存和计算。
- 高性能:相同价格可以提供更高的算力或者储存
- 可靠性
- 可扩展性
- 容错性
10. OS概念
- inode:Index Node是操作系统里用于管理文件和目录的数据结构。每个文件都有唯一的inode,其中包括文件类型文件所有者、文件权限、文件创建时间、文件修改时间等。还包含了指向文件数据块的指针,以便操作系统可以查找和读取文件的内容。每个文件系统都有其自己的inode表,其中存储了所有文件和目录的inode信息。
- mount:当我们在OS里操作mount的时候,实际上是把存储设备(如硬盘分区、网络存储)上的文件系统链接到你的文件系统的某个目录上。有利于从本来操作系统来访问外部硬件。
- paging:分页是一种内存管理技术,将物理内存划分为固定大小的页框,将进程的虚拟地址空间划分为相同大小的页面。操作系统使用页表来映射虚拟页面到物理页框,允许非连续的虚拟地址在连续的物理内存中存储。这提高了内存的利用率和地址空间的管理效率。
- swapping:1. 交换是一种内存管理技术,当系统中的物理内存不足时,操作系统将不活跃的进程或进程的部分数据从内存中移到磁盘上的交换文件。这样可以释放内存以供活跃进程使用,但会导致磁盘I/O延迟。当需要恢复进程时,数据从磁盘交换文件重新加载到内存中。