运维知识体系

面试知识体系:

es原理:
https://blog.csdn.net/opensure/article/details/57130327

acl
99%:表示 一年宕机时间不超过4天

99.9% :表示一年宕机时间不超过10小时

99.99%: 表示一年宕机时间不超过1小时

99.999% :表示一年宕机时间不超过6分钟

系统方面:

系统:
    1、僵尸进程、孤儿进程
        孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

          僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
        
        僵尸进程危害:
        如果进程不调用 wait/waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的。
        如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
        避免方法:
            1)、通过信号机制
            子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程
            2)、fork两次,进程fork一个子进程,然后再fork一个孙进程,然后子进程退出。这样孙进程变成孤儿进程由init接管
          
        发现定位和处理
        top中可以发现僵尸进程,
        定位:ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]',找到标识为z的僵尸进程的pid和ppid
        杀死需要用hup参数:
        kill -HUP 僵尸进程父ID
    2.标准大页、透明大页
        Huge pages  是从 Linux Kernel 2.6 后被引入的,目的是通过使用大页内存来取代传统的 4kb 内存页面, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。
        Transparent Huge Pages  缩写  THP ,这个是 RHEL 6 开始引入的一个功能,在 Linux6 上透明大页是默认启用的。
        这两者最大的区别在于 :  标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。不建议对数据库工作负载使用  THP。

    3、常用系统性能分析命令
        https://www.cnblogs.com/passzhang/articles/8592864.html

    4、如何查看内存插槽情况
        1)、查看内存槽数、那个槽位插了内存,大小是多少
            dmidecode|grep -P -A5 "Memory\s+Device"|grep Size|grep -v Range
        2)、查看最大支持内存数
            dmidecode|grep -P 'Maximum\s+Capacity'
        3)、查看槽位上内存的速率,没插就是unknown。
        dmidecode|grep -A16 "Memory Device"|grep 'Speed'
    
    5、如何检查磁盘坏块:
        1)、Smartctl、MegaCli
        2)、badblocks -s -v /dev/sdnx
        # 其中n表示硬盘设备名,x表示硬盘对应的分区号。例如需要检查“/dev/sda2”,执行命令如下:

    6、ansible  puppet
        ansible:基于python,使用ssh协议,没有cli,是推模式,效率低,不适合大规模。使用yml文件配置,简单
        puppet:基于ruby,使用http协议,c/s,是拉模式,接口全面,适合大规模。也可以用ansible调用puppet。

    7、zabbix 普罗米  
        Prometheus
        https://www.jianshu.com/p/0978f3b3d843?utm_campaign=haruki

    8、k8s  docker原理
    dockerfile参数说明:https://www.cnblogs.com/panwenbin-logs/p/8007348.html


    9、报警收敛怎么做,设置报警级别,根据不同的阈值调用不用的报警机制予以区分,设置维护时段,精细划分等
    10、前后端交互怎么实现,django-mtv   mvc
    11、CPU系统调用占比多的问题排查思路
        排查思路:
            使用vmstat查看系统维度的CPU负载

            使用top查看进程维度的CPU负载
        推测:
        这程序使用很多system call,如read,write,select
        使多数时间运行在kernel space.

        这说明你的程序在执行过程中,有如下几种情况中的一种或者多种情况发生:
            1. 进入了一个死循环无法跳出来;
            2. 也许是一直在等待一个信号,如从dbus上读取一个你需要的信息;
            3. 有可能是你的程序在对一个非常大的内容进行分析和处理;
            4. 有可能是你的程序要处理的问题比较多,所以在一个个慢慢的执行。
            
            大部分是由上面四种情况引起的,在这四种情况中,第一种情况坚决要避免,因为不如此,那么你的CPU资源将会被吃光。第二种情况,我的想法是,你要修改一下,看看有没有什么更快,更高效的方法来获取到需要的信号,或者是不去获取信号,而是改用其他方式来处理。第三和第四两种情况,就要根据你的实际需要来定了。如果是必须这样做,那么也只能够耐心的等待了。但是可以考虑优化代码,优化算法的方式来提高效率。
            Linux系统下有个很好的调试工具gdb。如果不知道自己的程序出现了什么问题,可以利用gdb工具逐步执行,去查找错误所在。
        
        分析案例:
            https://blog.csdn.net/qinshi501/article/details/77442770
            步骤一:找到最耗CPU的进程,top找到pid
            步骤二:找到最耗CPU的线程,top -Hp 10765 ,显示一个进程的线程运行信息列表
            步骤三:将线程PID转化为16进制 ,方法:printf “%x” 10804,之所以要转化为16进制,是因为堆栈里,线程id是用16进制表示的。
            步骤四:查看堆栈,找到线程在干嘛,jstack 10765 | grep ‘0x2a34’ -C5 --color

web:
    1、http:status code:301 302、502

        2开头 (请求成功)表示成功处理了请求的状态代码。
        3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
        4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理
        5开头 (服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错
    
        301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
        302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    
        400   (错误请求) 服务器不理解请求的语法。 
        401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
        403   (禁止) 服务器拒绝请求。
        404   (未找到) 服务器找不到请求的网页。
        405   (方法禁用) 禁用请求中指定的方法。
    
        500   (服务器内部错误)  服务器遇到错误,无法完成请求。 
        501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
        502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
        503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
        504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
        505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
        https://blog.csdn.net/qq_35779969/article/details/80753197


    2、http工作原理:
        https://www.cnblogs.com/qdhxhz/p/8468913.html

    3、nginx的优化
        https://www.cnblogs.com/cheyunhua/p/10670070.html

    4、DNS、CDN
        DNS:https://www.cnblogs.com/zhangxingeng/p/9970733.html

        dns解析慢:换知名的dns,或者开始本地缓存,设置使用谷歌DNS服务,同时开启dnsmasq的本地缓存(可以大幅提高重复访问网站时的响应速度)。
        cdn:核心节点、边缘节点、优质资源,基调的打点测试,网宿蓝汛、防盗链,跨域设置,回源策略,数据预热。

    5、网页打开慢,排查思路:
        根据用户访问的路径,可以分为几个方向:
        1、网络问题:
            1)用户的本地网络问题,比如本地路由器dns劫持,大部分站点都被运营商缓存,ping服务端ip,看是否有丢包以及rt情况。
            2)用户的网络跟服务端的运营商不同引起的跨运营商的带宽打压。
            3)tracert 追踪用户访问站点过程中每个跳转点是否正常。
        2、页面问题:
            1)找到请求的url,打开f12,分析请求过程中耗时比较大的地方,
            2)如果是大图,可以找研发裁图,
            3)如果是静态资源从cdn获取慢,可以用基调对这个地区进行检测,对应慢的点,找cdn厂商做下优化,
            4)有跳转其他站点资源的,最好能把资源拔下来做缓存,或者挑个更快些的站点
        3、后端原因:
            1)找到对应的应用逻辑,模拟访问后,在后端追踪日志,或者抓包查看是哪一步比较慢
            2)中间件命中率低,回源率高
            3)后端sql有问题,查询效率慢,或者数据库压力大,处理效率低
            4)后端资源不足,io性能低,tcp连接释放慢,网卡带宽水位比较满,机头的并发处理到上限了等等。

数据库:

    0、一致性哈希、哈希

     https://www.cnblogs.com/lpfuture/p/5796398.html


    1、redis:
        雪崩:key过期时间比较集中,批量失效后,大量请求直接落到数据库上,导致后端库崩溃。
            解决思路:
                    1、定期刷新缓存;
                    2、因为redis单进程单线程,在前端加入一个队列或者锁,某个key,始终只有一个线程在写;
                    3、在过期时间上加个随机数,setRedis(key, value, time+Math.random()*10000);
                    4、做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

        穿透:是指缓存和后端数据都没有数据,但是用户或者黑客一直请求,导致后台数据库压力较大;
            解决思路:
                    1、将查询为空的结果也进行缓存;
                    2、前端拦截不合法的情况;可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。
                    
        击穿:指热点数据突然失效,导致大量的热点请求落到数据库,引起后端压力大甚至崩溃。
            解决思路:
                    1、打散热点,加互斥锁
                    2、设置永久有效期

        脑裂:因为主从之间网络问题导致超过主从检测的心跳超时时间,从库升级为主库,主库的状态不变,
            解决思路:通过设置最小从节点数,和超时时间,当主节点网络不可达,集群切换到slave,master恢复后,他的slave节点不够时就会
        
        redis集群高可用的原理
        三主三从,实现数据分片存储,基本原理是,设置2的14次方16384个slot切分到对应的主节点上,数据写入对应的槽位,然后每个主分片有一主一从,通过failover机制进行主从切换,只要同一节点不在相同宿主机上,或者相同机柜上,集群出问题的概率比较小。

        redis日常问题处理:
            大key的分析,过期数据的清理,

            由于RDB,执行是会阻塞主进程,因此一般不开,aof空间占用比较大,为了保证线上环境性能和稳定性,可以吧rdb和aof放到slave上做。


        https://baijiahao.baidu.com/s?id=1660009541007805174&wfr=spider&for=pc

    2、mysql:主从同步原理
        slave启动iothread,去master链接,mastar启动一个dump binlog的线程将这部的数据变更发送到slave的io线程,io线程将读到的binlog写入relaylog,然后再又sql线程将relaylog回放到从库。

    3、es:缺点:并发处理较弱

    ==
    数据库乐观锁与悲观锁?
    并发控制: 事务和锁的存在都是为了更好的解决并发访问造成的数据不一致性的的问题
    乐观锁和悲观锁都是为了解决并发控制问题, 乐观锁可以认为是一种在最后提交的时候检测冲突的手段,而悲观锁则是一种避免冲突的手段。
    乐观锁: 是应用系统层面和数据的业务逻辑层次上的(实际上并没有加锁,只不过大家一直这样叫而已),利用程序处理并发, 它假定当某一个用户去读取某一个数据的时候,其他的用户不会来访问修改这个数据,但是在最后进行事务的提交的时候会进行版本的检查,以判断在该用户的操作过程中,没有其他用户修改了这个数据。开销比较小
    乐观锁的实现大部分都是基于版本控制实现的,

    https://blog.csdn.net/qq_42765168/article/details/81514481

    数据库索引,底层是怎样实现的,为什么要用B树索引

    查询中哪些情况不会使用索引?

    数据库如何设计:范式规范:
        1nf:确保每一列的原子性,每一列都是不可拆分的最小数据单元
        2nf:基于1nf,表中所有列都必须依赖于主键,一张表只说明一件事
        3nf:基于1nf2nf,表中所有属性只能依赖于主键,都是直接相关,不能间接相关
        bcnf:没有外键,既bc范式
        通俗:第一范式和第二范式在于有没有分出两张表,第二范式是说一张表中包含了多种不同的实体属性,那么要必须分成多张表, 第三范式是要求已经分成了多张表,那么一张表中只能有另一张表中的id(主键),而不能有其他的任何信息(其他的信息一律用主键在另一表查询)。

        【数据库五大约束】

        1.primary KEY:设置主键约束;
        2.UNIQUE:设置唯一性约束,不能有重复值;
        3.DEFAULT 默认值约束,height DOUBLE(3,2)DEFAULT 1.2 height不输入是默认为1,2
        4.NOT NULL:设置非空约束,该字段不能为空;
        5.FOREIGN key :设置外键约束。

        https://blog.csdn.net/qq_40722284/article/details/82461747?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

    数据库索引是什么结构? B-tree的结构,h是tree的深度,d是大于1的整数,也是tree的度。每个tree至少由2个指针和一个key组成,既n个指针和n-1个key

    B-Tree查找数据
    B-Tree是一个非常有效率的索引数据结构。这主要得益于B-Tree的度可以非常大,高度会变的非常小,只需要二分几次就可以找到数据。例如一个度为d的B-Tree,设其索引N个key,则其树高h的上限为logd((N+1)/2)),检索一个key,其查找节点个数的渐进复杂度为O(logdN)。

    在B-Tree中按key检索数据的算法非常直观:

        首先从根节点进行二分查找,如果找到则返回对应节点的data
        否则对相应区间的指针指向的节点递归进行查找,如果找到则返回对应节点的data
        如果找不到,则重复过程2,直到找到节点或找到null指针,前者查找成功,后者查找失败。

    https://www.cnblogs.com/songwenjie/p/9414960.html

    B+树是怎么样的结构?

    区别于B-Tree:每个节点的指针上限为2d而不是2d+1,内节点不存储data,只存储key;叶子节点不存储指针

    B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;

       B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;

       所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

       B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

    聚集索引和非聚集索引区别:https://blog.csdn.net/riemann_/article/details/90324846

    数据是怎么分布的?
    https://blog.csdn.net/csdnlijingran/article/details/102309593
    一般B+树有多少层?innodb B+tree 3层,存2kw左右条数据 https://blog.csdn.net/csdnlijingran/article/details/102309593
    二分查找是什么?
    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。 

开发:
    算法:
    0、二分查找:
    def bin_search(data_list, val):    
    low = 0                         # 最小数下标    
    high = len(data_list) - 1       # 最大数下标    
    while low <= high:        
            mid = (low + high) // 2     # 中间数下标        
            if data_list[mid] == val:   # 如果中间数下标等于val, 返回            
                return mid        
            elif data_list[mid] > val:  # 如果val在中间数左边, 移动high下标            
                high = mid - 1        
            else:                       # 如果val在中间数右边, 移动low下标            
                low = mid + 1    
        return # val不存在, 返回None
    ret = bin_search(list(range(1, 10)), 3)
    print(ret)

    1、斐波那契数列 数列
    def fib_loop_while(max):
    a, b = 0, 1
    while max > 0:
        a, b = b, a + b
        max -= 1
        yield a

    for i in fib_loop_while(10):
    print(i)

    2、1-n之间,包含7的数字,剔除出来,返回个数。
        def test(num):
            l=(len(str(num)))
            b = []
            while l>0 :
                l -= 1
                a = int(num%10)
                num = num/10
                b.append(a)
                continue
            return(b)

        for i in range(402):
            res = test(i)
            if 7 in res:
                print(i)

    3、素数判断:
    #!/usr/bin/env python
    # --*-- coding = utf-8 --*--
    
    def isPrime(n):
        if n <= 1:
            print("isnot prime2")
            return False
        i = 2
        while i*i <= n:
            if n % i == 0:
                print("isnot prime1")
                return False
            i += 1
        print(n)
        return True
    
    
    isPrime(6)

    4、投掷两个色子n次的和为6或者其中有一个为6的结果返回

    #!/usr/bin/env python
    # --*-- coding = utf-8 --*--
    
    import random
    
    def roll_rand():
        res = random.randint(1,6)
        return res
    
    roll_list1 = []
    roll_list2 = []
    total_num = 100
    result_list = []
    
    def main():
        for i in range(total_num):
            res1 = roll_rand()
            res2 = roll_rand()
            roll_list1.append(res1)
            roll_list2.append(res2)
            result_list.append([res1,res2])
            r3 = res1+res2
            if res1 == 6 or res2 == 6 or r3 == 6:
                print(i, ":", result_list[i])
            else:
                continue
    
    if __name__ == '__main__':
        main()

    5、分别返回60-80-100之间的人。

    三元运算:
    [on true] if [expression]else [on false]

    shell:sed awk    grep

    python:十大排序:
        https://www.cnblogs.com/Y-xp/p/11668278.html
        https://www.cnblogs.com/onepixel/articles/7674659.html

    时间复杂度、空间复杂度:https://blog.csdn.net/haha223545/article/details/93619874

    java:
    链接:https://www.nowcoder.com/discuss/415817


    Java容器有哪些?
    https://blog.csdn.net/qq_35771266/article/details/97156939

    1.常用容器分类 JAVA中的容器类主要分为两大类,一类是Map类,一类是Collections类,他们有一个共同的父接口Iterator,它提供基本的遍历,删除元素操作。
    2.Iterator类 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。 
    哪些是同步容器,哪些是并发容器?
    https://www.cnblogs.com/konck/p/9473665.html
    
    新生代分为几个区?使用什么算法进行垃圾回收?为什么使用这个算法?
    HashMap put方法的执行过程?
    https和http区别
    线程池的工作原理,几个重要参数,饱和策略
    
    select poll epoll的区别
    Redis支持的数据类型(必考)
    zset跳表的数据结构(必考)
    
    LinkList和ArrayList
    
    给你一个集合{0,1,2,3,4},用python找出所有的子集
    
    Python打开一个文件,找出某个字符串最快的方法
    写一个awk 打印出第10行
    一个列表,找出三个数的和等于19,代码实现

    python基础:https://www.liujiangblog.com/course/django/84

    微服务:rpc框架,如dubbo、springcloud、grpc、thrift、tars、motan。
    比较核心的思想是:服务注册,无状态,每个原子服务都可以横向

网络:

    1、.ddos攻击是什么?怎么防御?

    2、tcp/ip
        tcp滑动窗口原理和机制:TCP是全双工通信,因此每一方的滑动窗口都包括了接收窗口+发送窗口,接收窗口负责处理自己接收到的数据,发送窗口负责处理自己要发送出去的数据。滑动窗口的本质其实就是维护几个变量,通过这些变量将TCP处理的数据分为几类,同时在发送出一个报文、接收一个报文对这些变量做一定的处理维护。

        总结就是:(1)滑动窗口允许发送方连续发送多个报文(2)根据对方接收窗口大小限制发送方的发送速率,防止拥塞

        https://www.cnblogs.com/shen-qian/p/12111666.html

        快速重传机制:三个相同序号的确认应答之后,对端会进行重传,这个是快速重传
        https://www.cnblogs.com/hujinshui/p/10472671.html

    3、抓包分析:
        tcpdump wireshark
        https://www.jianshu.com/p/a62ed1bb5b20

    4、常用网络分析工具:
        https://blog.csdn.net/comprel/article/details/96642176

        nethogs  进程的网络占用
        strace  进程追踪
        lsof 按进程ID列出包括套接字细节在内的打开的文件
        ss 套接字统计信息
        nfsstat nfs服务器与客户机统计信息
        iftop 主机 统计网络接口吞吐量
        /proc/net 包含许多网络统计信息文件
        traceroute  路由跟踪
        tracert 追踪请求站点的路径
        tcpdump
        nslookup 用于查询DNS的记录,查询域名解析是否正常,在网络故障时用来诊断网络问题

你可能感兴趣的:(平日杂谈)