测试开发面试题总结

排序算法的稳定性:
稳定性,如果元素A和B相等,A在排序之前在B的前面,排序后仍在B的前面
堆排序、快速排序、希尔排序、直接选择排序是不稳定的排序算法,而冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。

进程和线程的区别?
1.进程是资源分配的最小单位,线程是CPU调度的最小单位
2.每个进程有自己的PCB,有单独的代码和地址空间。而一个进程下的线程共享代码和地址空间。
3.线程相比于进程,线程间切换的消耗更小。
4.但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间

https的握手机制?
客户机发出hello连接请求,附上自己支持的安全协议的版本,能够使用的加密套件的列表等相关信息。
服务器回应hello请求,根据本机上能使用的加密套件,发送此次握手使用的协议版本,哪种加密套件以及自己的证书。
客户机收到信息后,验证证书真伪,如果通过验证就在本地生成通讯密钥,通过公钥加密发送给服务器
服务器收到信息后,通过私钥解密获得通讯密钥
后续通讯均通过通讯密钥加密进行

滑动窗口机制
窗口就通过滑动的方式,向后移动,确保下一次发送仍然可以发送窗口大小的数据包。这样的发送方式被称为滑动窗口机制,接收方每次收到数据后,就会根据协议字段中的窗口大小字段来告诉发送方最多继续发送多少数据,当窗口大小为0时表示不需要再发送数据了

三次握手、四次挥手
三次握手
第一次,客户端TCP向服务端TCP发送请求连接报文段,发送一个TCP标志位SYN=1,服务器收到请求,明白客户端想要请求连接
第二次,服务端确认连接,向host1发送应答号ACK=1、SYN=1,并为TCP分配地址和变量
第三次,客户端收到请求并确认,给TCP分配地址和变量
为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

为什么不能用两次握手进行连接?
答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

如果已经建立了连接,但是客户端突然出现故障了怎么办?
答:TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事务的并发操作中可能会出现脏读,不可重复读,幻读。下面通过事例一一阐述它们的概念与联系。
  脏读、不可重复读、幻象读概念说明:  
  脏读:指当一个事务正在访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。
  不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。
  幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)

Q0.数据库索引有哪些,优缺点?
hash索引和B+树索引
hash索引等值查询效率高,但是不能排序,因此不能进行范围查询
B+树索引数据有序,能够进行范围查询

ping命令的作用和原理
作用:简单来说,「ping」是用来探测本机与网络中另一主机之间是否可达的命令,如果两台主机之间ping不通,则表明这两台主机不能建立起连接。ping是定位网络通不通的一个重要手段。
原理:ping 命令是基于 ICMP 协议来工作的,「 ICMP 」全称为 Internet 控制报文协议( Internet Control Message Protocol)。ping 命令会发送一份ICMP回显请求报文给目标主机,并等待目标主机返回ICMP回显应答。因为ICMP协议会要求目标主机在收到消息之后,必须返回ICMP应答消息给源主机,如果源主机在一定时间内收到了目标主机的应答,则表明两台主机之间网络是可达的
 
Q1.为什么不用二叉查找树作为数据库索引?
二叉查找树,查找到指定数据,效率其实很高logn。但是数据库索引文件有可能很大,关系型数据存储了上亿条数据,索引文件大则上G,不可能全部放入内存中,
而是需要的时候换入内存,方式是磁盘页。一般来说树的一个节点就是一个磁盘页。如果使用二叉查找树,那么每个节点存储一个元素,查找到指定元素,需要进行大量的磁盘IO,效率很低。
而B树解决了这个问题,通过单一节点包含多个data,大大降低了树的高度,大大减少了磁盘IO次数。

Q2.B树和二叉查找树的性能对比?
B树包括B+树的设计思想都是尽可能的降低树的高度,以此降低磁盘IO的次数,因为一个索引节点就表示一个磁盘页,页的换入换出次数越多,表示磁盘IO次数越多,越低效。
B树算法减少定位数据所在的节点时所经历的磁盘IO次数,从而加快存取速度。
假设一个节点可以容纳100个值,那么3层的B树可以容纳100万个数据。(根节点100值,第二层可以存储99个节点(k-1),也就是99100 个值,第三层可以存储
(99
100-1)*100)结果是近似100万个数据。而如果使用二叉查找树,则需要将近20层,也就是进行20次磁盘IO,性能差距如此之大。
如mongoDB数据库使用,单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。

Q3.B+对比B树的优点?
因为B树的每个节点除了存储指向子节点的索引之外,还有data域,因此单一节点存储的指向子节点的索引并不是很多,树高度较高,磁盘IO次数较多,
而B+树单一节点存储的指向子节点的索引更多,B+树空间利用率高,因此B+树高度更低,磁盘IO次数更少,性能更好。
因为B树的中间节点存储了数据,所以整个树的每一层都有可能查找到要查找的数据,查询性能不稳定,
而B+树所有的data都存储在叶子节点,且叶子节点位于同一层,因此查询性能稳定。
B树如果想要进行范围查找,需要频繁的进行二叉树的中序遍历,进行范围查找比较复杂,
B+树要查找的元素都位于叶子节点,且连接形成有序链表,便于范围查找。

Q4.B树,B+树使用场景。
B树主要用于文件系统,和部分数据库索引,如文档型数据库mongodb
B+树主要用于mysql数据库索引。

Q5.为什么数据库索引不用红黑树而用B+树?
红黑树当插入删除元素的时候会进行频繁的变色与旋转(左旋,右旋),来保证红黑树的性质,浪费时间。
但是当数据量较小,数据完全可以放入内存中,不需要进行磁盘IO,这时候,红黑树时间复杂度比B+树低。
比如TreeSet TreeMap 和HashMap (jdk1.8)就是使用红黑树作为底层数据结构。
数据库之三范式
属于第一范式关系的所有属性都不可再分,即数据项不可分。
若某关系R属于第一范式,且每一个非主属性完全函数依赖于任何一个候选码,则关系R属于第二范式。
第三范式:非主属性既不传递依赖于码,也不部分依赖于码。
二叉树排序

2、输入一个网址,你看到他的过程是什么
从用户输入一个网址到网页最终展现到用户面前,中间的大致流程总结如下:

  1. 在客户端浏览器中输入网址URL。
  2. 发送到DNS(域名服务器)获得域名对应的WEB服务器的IP地址。
  3. 客户端浏览器与WEB服务器建立TCP(传输控制协议)连接。
  4. 客户端浏览器向对应IP地址的WEB服务器发送相应的HTTP或HTTPS请求。
  5. WEB服务器响应请求,返回指定的URL数据或错误信息;如果设定重定向,则重定向到新的URL地址。
  6. 客户端浏览器下载数据,解析HTML源文件,解析的过程中实现对页面的排版,解析完成后,在浏览器中显示基础的页面。
  7. 分析页面中的超链接,显示在当前页面,重复以上过程直至没有超链接需要发送,完成页面的全部显示。
    简单总结
    1、输入网址
    2、DNS解析
    3、建立tcp连接
    4、客户端发送HTTP请求
    5、服务器处理请求 
    6、服务器响应请求
    7、浏览器展示HTML
    8、浏览器发送请求获取其他在HTML中的资源。

二叉查找树(Binary Search Tree):或者是一颗空树,或者是具有下列性质的二叉树:
1、若它的左子树不空,则其左子树上的所有结点的值均小于它根结点的值;
2、若它的右子树不空,则其右子树上的所有结点的值均大于它根结点的值;
3、它的左、右子树也分别为二叉查找树。

3、想要为每个方法加一个查看运行时间的功能该怎么做(应该Annotation,没答出来)
在方法开始只是加一个start时间time.time()
方法结束时再加一个end时间time.time()
两个只差就是运行时间

在浏览器中输入url,经历的过程
1.浏览器向服务器发出url请求,服务器解析域名对应的ip地址
2.通过ip地址和默认端口号建立TCP连接
3.浏览器发出HTTP请求
4.服务器对请求做出响应
5.释放TCP连接
6.浏览器将html文件解析并在网页展示

如何避免死锁
在并发程序中,避免了逻辑中出现复数个线程互相持有对方线程所需要的独占锁的的情况,就可以避免死锁

TCP为什么使用基于流式的传输
TCP为了保证可靠传输,尽量减少额外开销(每次发包都要验证),因此采用了流式传输,面向流的传输,相对于面向消息的传输,可以减少发送包的数量,从而减少了额外开销

红黑树和hash,在选择时用的时候有什么依据
红黑树是有序的,Hash是无序的,根据需求来选择。
红黑树占用的内存更小(仅需要为其存在的节点分配内存),而Hash事先就应该分配足够的内存存储散列表(即使有些槽可能遭弃用)。
红黑树查找和删除的时间复杂度都是O(logn),Hash查找和删除的时间复杂度都是O(1)

4、分页和分段,
1.在该方式中,将用户程序地址空间分为若干固定大小的区域,称为“页”或“页面”。典型的页面大小为1KB。相应的,也将内存空间分为若干个物理块或页框(frame),页和块的大小相同。这样可将用户程序的任一页放入任一物理块中,实现了离散分配。
2.这是为了满足用户要求而形成的一种储存管理方式。它把用户程序的地址空间分为若干个大小不同的段,每段可定义一组相对完整的信息。在储存器分配时,以段为单位,这些段在内存中可以不相邻接,所以也同样实现了离散分配。

3.段页式储存管理方式
这是分页和分段两种储存管理方式相结合的产物。程序的地址空间划分为多个拥有独立地址空间的段,每个段上的地址空间划分为大小相同的页。这样既拥有分段系统的共享保护,又拥有分页系统的虚拟内存功能。它兼具两者的优点,是目前应用较为广泛的一种储存管理方式。

  1. 分页置换算法
    6、进程间通信方式
    信号量、管道、有名管道、共享内存、消息队列
    7、写了一道group by+子查询的题
    8、编程:100盏灯,全部关闭,第一人全部打开(亮),第二个人隔一个按开关(2、4、6、8、10), 第三个人隔2个按开关(3、6、9、12),以此类推,第100人路过时有几盏灯亮着?

1.synchronized 关键字底层原理

https过程
1、TCP 三次同步握手
2、客户端验证服务器数字证书
3、DH 算法协商对称加密算法的密钥、hash 算法的密钥
4、SSL 安全加密隧道协商完成
5、网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改。

3、mysql的隔离级别
4个隔离级别:从高到低依次是,读未提交、读提交、可重复读、序列化

4、mysql的引擎
MEMORY
使用存在于内存中的内容创建表,每一个memory只实际对应一个磁盘文件。因为是存在内存中的,所以memory访问速度非常快,而且该引擎使用hash索引,可以一次定位,不需要像B树一样从根节点查找到支节点,所以精确查询时访问速度特别快,但是非精确查找时,比如like,这种范围查找,hash就起不到作用了。另外一旦服务关闭,表中的数据就会丢失,因为没有存到磁盘中。

1.mysql中为什么用B+树
相比于hash索引,B+树索引可以实现范围查找
相比于B树来说,B+树IO次数更少,遍历更加方便
B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小
B+树的查询效率更加稳定
B+树便于遍历
更适合基于范围的查询
3、讲一讲索引,最左匹配原则
最左匹配原则:最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

4、什么是SQL注入,怎么预防
sql注入:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库执行一些恶意的操作
防止策略 
1.严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害 
2.检查输入的数据是否具有所期望的数据格式,严格限制变量的类型
3.对进入数据库的特殊字符(’” \ 尖括号 & * ;等符号)进行转义处理,或编码转换。

5、你知道什么常见的网络攻击(讲了DOS、DDOS)
常见的网络攻击:1、口令入侵,是指使用某些合法用户的帐号和口令登录到目的主机;2、特洛伊木马,常被伪装成工具程式或游戏等诱使用户打开;3、WWW欺骗,正在访问的网页已被黑客篡改过;4、节点攻击;5、网络监听,是主机的一种工作模式。

6、一个开放的场景题:北京有2个机场,大兴和首都,位于两个不同方位,假设每2分钟起降一艘飞机,那么怎么估算北京上空有几架飞机

sar命令:用这个命令查看所有CPU核心使用率,top只能查看前48个

进程在什么情况下从用户态切换到内核态?
所有中断服务程序都属于内核代码。如果一个中断产生时任务正在用户代码中执行,那么该中断就会引起CPU特权级从3级到0级的变化,此时CPU就会进行用户态堆栈到内核态堆栈的切换操作

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

元组和列表的关系?

说说你对视图的理解

KNN和K-means的区别
首先,这两个算法解决的是数据挖掘中的两类问题。K-Means 是聚类算法,KNN 是分类算法。其次,这两个算法分别是两种不同的学习方式。K-Means 是非监督学习,也就是不需要事先给出分类标签,而 KNN 是有监督学习,需要我们给出训练数据的分类标识。最后,K 值的含义不同。K-Means 中的 K 值代表 K 类。KNN 中的 K 值代表 K 个最接近的邻居。

KNN算法是分类算法,分类算法肯定是需要有学习语料,然后通过学习语料的学习之后的模板来匹配我们的测试语料集,将测试语料集合进行按照预先学习的语料模板来分类
Kmeans算法是聚类算法,聚类算法与分类算法最大的区别是聚类算法没有学习语料集合。

线程同步的方式?(没答好)
1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
2)互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
3)信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。
4)事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作。

python解决高并发的方式
1.队列,按照先后顺序进行排序
2.上锁,
3.信号中间件
4.预处理
5.并行
6.提速

什么是视图
是一种虚拟的表,即视图所对应的数据不进行实际存储,但具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。

深拷贝浅拷贝的区别?
假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)

等号“=”是深拷贝还是浅拷贝?(我前面一问回答的时候还特意把等号区分开来了,说三者的不同,然后又问等号“=”属于哪一类,我裂开了,我就又说了一遍等号赋值的特点)

reduce函数实现阶乘。

数据库中的事务是什么?
数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行,因此事务是一个不可分割的工作逻辑单元

数据库中锁按照锁的范围分为什么?
行锁、页锁
行锁什么时候用到?表锁什么时候用到
行锁一锁锁一行或者多行,表锁是锁住一张表。有索引的时候就是用行锁,没有索引的时候就是用表索

MySQL里面有尝试过提高查询速度?(感觉没答好,我答了数据库优化的四个方面,面试官又反问还有吗?我就把建立索引的几个标准说出来,面试官有说“这是索引”,针对查询语句的优化还有哪些?我裂开了)
MySQL数据库优化的八种方式
1.选取最适用的字段属性
2.使用连接join(JOIN)来代替子查询(Sub-Queries)
3.使用联合union(UNION)来代替手动创建的临时表

4.事务:当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方式,这样可以保证用户的操作不被其它的用户所干扰
5.使用外键,锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键
6.使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显
7.锁定表
8.优化查询语句

sql关键字的执行顺序
from->on->join(各种join)->where->group by->having->select->distinct->union->order by ->limit

为什么用Redis?(答了Redis的优点,快!数据持久化之类)
Redis嘛,就是一种运行速度很快,布置实施起来相对简单。并发很强、是跑在内存上的NoSql数据库,支持键到五种数据类型的映射。

Mysql
快?那和存在DB里面有什么差异吗?(我就答了关系型和非关系数据的区别)
Redis的基本数据结构?string,list,hash、set、zset
Linux命令:查询IP?
ip addr
hostname -I
ifconfig
查询句柄泄露?(没接触过)
1.通过 ps -aux | grep 进程名 来找到进程ID
2.通过 ls -la /proc/进程ID/fd 可以棑看文件信息,文件句柄非Socket的可以查看文件路径
查询某个进程占用内存情况?
ps -ef | grep kafka
top -p 2913
ps aux | grep 进程名

查询某个端口是否被占用?(后来百度发现是 netstat -anp |grep 端口号,我裂开,我把anp记成了ano,面试官已经知道我的linux全靠记了)
netstat -anp | grep 端口号

I/O多路复用(multiplexing)的本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作

poll和epoll的区别?(全屏记忆,答得零零散散的)
阻塞IO和非阻塞IO的区别?(阻塞IO不太了解)
UDP实现数据可靠怎么做?(答的是在应用层按照TCP的可靠原则实现对UDP的可靠性)
具体说一下?(TCP有滑动窗口、流量控制和拥塞控制,在应用层可以按照这些对UDP进行实现)
比如拥塞控制应该怎么做?(不太了解)
怎么判断UDP数据丢了?(裂开,我答的对数据进行编号)
但是UDP是无序的,怎么处理呢?(想TCP一样,用接收窗口,窗口内的数据有序之后,再做后续操作)
如果现在数据到的顺序是1,2,7,返回的序列号是多少?(我答的ack位是3,同时7这条数据会保留,在接收了3456之后,因为自己保留了7,所以收到6之后的ack会变成8,因为7我们保留了)
7会重发吗?(不会,我是不是前面一问答错了)

线程同步的方式
互斥锁
信号量
读写锁
条件变量
python实现快速排序
def partition(arr,low,high):
i = low-1
pivot = arr[high]
for j in range(low,high):
if arr[j] <= pivot:
i+=1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return (i+1)
def quickSort(arr,low,high):
if low<high:
pi = partition(arr,low,high)

	quickSort(arr,low,pi-1)
	quickSort(arr,pi+1,high)

arr = [10,7,8,9,1,5]
n = len(arr)
quickSort(arr,0,n+1)
print(“排序后的数组”)
for i in range(n):
print("%d" %arr[i])

垃圾回收整理
什么是垃圾回收
程序在运行时必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,终将导致内存溢出,所以对内存资源的管理是非常重要的
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光

垃圾回收算法
常见的有:引用计数法、标记清除法、标记压缩法、复制算法、分代算法
1.引用计数法
假设有一个对象为A,任何一个对象的引用,那么对象A的引用计数器+1,当引用失败时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,可以被回收
优缺点:
(1).实时性高,无需等到内存不够的时候,才开始回收,运行时根据对象的计时器是否为0,就可以直接回收
(2).在垃圾回收过程中,应用无需挂起,
(3).区域性,更新对象的计数器时,只是影响到该对象,不会扫描全部对象
(4).每次对象被引用时,都需要去更新计数器,有一点时间开销
(5).浪费cpu资源,即使内存够用,仍然在运行时进行计数器的统计
(6).无法解决循环引用问题

标记清除法
标记清除算法,是将垃圾回收分为两个阶段,分别是标记和清除
标记:从根节点开始标记引用的对象
清除:未被标记引用的对象就是垃圾对象,可以被清理

去除一个ArrayList的重复元素有两种方法:(ArrayList与Vector的存储结构是Object[],LinkedList是双向列表):
  第一种是不需要借助临时list,用equals方法比较ArrayList中数据,两次遍历原来list;
  第二种是借助一个临时ArrayList,向临时List添加数据,调用arrayList.contains(obj)判断是否存在

BIO:同步阻塞式IO,服务器实现模式为一个连接建立一个线程,即客户端有连接请求时,服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情,会造成不必要的线程开销,可以通过线程池机制改善
NIO和BIO最大的区别就是只需要开启一个线程就可以处理来自多个客户端的IO事件
NIO:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器(Selector)上,多路复用器论询到连接有IO请求时才启动一个线程进行处理
BIO方式适用于连接数目比较小且固定的场景,这种方式对服务器资源要求比较高,并发局限于应用中
NIO适合处理连接数目特别多,但是连接比较短小的场景

头条刷不出来内容是什么问题:
1、检查网络连接是否稳定,更换网络尝试
2、更新头条版本尝试
3、清除app缓存,应用数据

为什么是四次挥手
因为在关闭连接是,服务端端可能还没有发送完数据,服务端在收到客户端的FIN关闭请求后,首先回发送一个ack作为应答,当所有数据都发送完成后才会发送FIN

Linux查看端口的指令
netstat -ano | grep

top - 15:54:23 up 39 days, 17:45, 1 user, load average: 0.10, 0.05, 0.00
Tasks: 91 total, 1 running, 90 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3%us, 0.3%sy, 0.0%ni, 99.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1018600k total, 524384k used, 494216k free, 15180k buffers
Swap: 0k total, 0k used, 0k free, 65660k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1414 root 20 0 779m 7832 1836 S 0.3 0.8 134:01.26 /usr/local/aegis/alihids/AliHids
3308 apache 20 0 366m 51m 3984 S 0.3 5.2 0:00.91 /usr/sbin/httpd
3309 apache 20 0 354m 39m 4272 S 0.3 4.0 0:00.45 /usr/sbin/httpd
3372 apache 20 0 368m 53m 4004 S 0.3 5.3 0:00.52 /usr/sbin/httpd
1 root 20 0 19232 372 84 S 0.0 0.0 0:02.57 /sbin/init

top命令 所显示信息的前五行是当前系统情况整体的统计情况。

第一行,任务队列信息,同 uptime 命令的执行结果,具体参数说明情况如下:

15:38:57 — 当前系统时间

up 39 days, 17:30 — 系统已经运行了39天17小时30分钟。

1 users — 当前有1个用户登录系统

load average: 0.10, 0.07, 0.01 — load average后面的三个数分别是1分钟、5分钟、15分钟的负载情况。

load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。

第二行,Tasks — 任务(进程),具体信息说明如下:

系统现在共有95个进程,其中处于运行中的有1个,94个在休眠(sleep),stoped状态的有0个,zombie状态(僵尸)的有0个。

第三行,cpu状态信息,具体属性说明如下:

us — 用户空间占用CPU的百分比。

sy — 内核空间占用CPU的百分比。

ni — 改变过优先级的进程占用CPU的百分比

id — 空闲CPU百分比

wa — IO等待占用CPU的百分比

hi — 硬中断(Hardware IRQ)占用CPU的百分比

si — 软中断(Software Interrupts)占用CPU的百分比

第四行,内存状态,具体信息如下:

total — 物理内存总量

used — 使用中的内存总量

free — 空闲内存总量

buffers — 缓存的内存量

第五行,swap交换分区信息,具体信息说明如下:

total — 交换区总量

used — 使用的交换区总量

free — 空闲交换区总量

cached — 缓冲的交换区总量

备注:

第四行中使用中的内存总量(used)指的是现在系统内核控制的内存数,空闲内存总量(free)是内核还未纳入其管控范围的数量。纳入内核管理的内存不见得都在使用中,还包括过去使用过的现在可以被重复利用的内存,内核并不把这些可被重新使用的内存交还到free中去,因此在linux上free内存会越来越少,但不用为此担心。

如果出于习惯去计算可用内存数,这里有个近似的计算公式:第四行的free + 第四行的buffers + 第五行的cached,按这个公式可计算出此台服务器的可用内存。

对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。

第六行,空行。

第七行以下:各进程(任务)的状态监控,项目列信息说明如下:

PID — 进程id

USER — 进程所有者

PR — 进程优先级

NI — nice值。负值表示高优先级,正值表示低优先级

VIRT — 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES

RES — 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA

SHR — 共享内存大小,单位kb

S — 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程

%CPU — 上次更新到现在的CPU时间占用百分比

%MEM — 进程使用的物理内存百分比

TIME+ — 进程使用的CPU时间总计,单位1/100秒

COMMAND — 进程名称(命令名/命令行)

状态码详解
500:服务器内部错误,无法完成请求

501:服务器不支持请求的功能,无法完成请求

502:作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应

503:由于超载或系统维护,服务器暂时的无法处理客户端的请求。

504:充当网关或代理的服务器,未及时从远端服务器获取请求

505:服务器不支持请求的HTTP协议的版本,无法完成处理

400:客户端请求的语法错误,服务器无法理解

401:请求要求用户的身份认证

402:保留,将来使用

403:服务器理解请求客户端的请求,但是拒绝此请求

404:服务器无法根据客户端的请求找到资源(网页)。

405:客户端请求中的方法被禁止

406:服务端无法根据客户端请求的内容特性完成请求

200:请求成功

204:无内容。服务器成功处理,但未返回内容,在未更新网页的情况,可确保浏览器继续显示当前文档

206:是对资源某一部分的请求

301:永久重定向,请求的资源已被永久的移动到新URL,返回信息会包含新的URL,浏览器会自动重定向到新的URL

302:临时重定向。与301类似,但资源只是临时被移动

303:查看其它地址。

304:未修改。所请求的资源未修改,服务器返回次状态码时,不会返回任何资源。

进程间通信
1.管道:管道是一种半双工的通信方式,数据只能单向流通,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2.有名管道:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信
3.信号量,信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。主要作为进程间以及同一进程间不同线程之间的同步手段
4.消息队列:消息队列是由消息的链表,存放在内核
5.信号:用于通知接收进程某个事件已经发生
6.共享内存:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,并可以让多个进程访问。
7.套接字:可用于不同设备及其间的进程通信

线程间通信
锁机制:包括互斥锁、条件变量、读写锁
互斥锁:提供了以排他方式防止数据结构被并发修改的方法
读写锁允许多个线程同时读共享数据,而对写操作是互斥的
信号量机制
信号机制

HTTP、TCP协议、IP协议分别位于哪一层
HTTP协议、TCP协议、IP协议分别在应用层,传输层,网络层。

get和post的区别
1.post更安全
2.post发送的数据更大(get有url长度限制)
3.post能发送更多的数据类型(get只能发送ASCII字符)
4.post比get慢
5.post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作

post请求的过程:

1.浏览器请求tcp连接(第一次握手)

2.服务器答应进行tcp连接(第二次握手)

3.浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

4.服务器返回100 continue响应

5.浏览器开始发送数据

6.服务器返回200 ok响应

get请求的过程

1.浏览器请求tcp连接(第一次握手)

2.服务器答应进行tcp连接(第二次握手)

3.浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

4.服务器返回200 ok响应

软件测试的完整流程
1.文档评审,需求文档、开发文档、测试计划
2.单元测试
3.敏捷测试
4.集成测试、系统测试
5.验收测试
6.确认测试、回归测试

单例模式的设计初衷:资源共享,只要初始化一次,就可以重复利用
饿汗单例模式:

饿汉单例模式:
优点:没有加任何锁,执行效率高。绝对的线程安全
缺点:类加载时就已经存在了,占用内存空间

懒汉单例模式
简单懒汉
加锁
利用内部类实现懒汉模式:利用内部类只有在外部类被加载时内部类才被加载

Mkdir -p 创建多级目录
Supervisor 是Linux下一个便利的启动和监控服务的命令

计算机网络应用层、传输层、网络层协议有哪些
应用层协议:
1.文件传输协议(FTP)
2.超文本传输协议(HTTP)
3.域名服务协议(DNS)
4.简单邮件传输协议(SMTP)
5.邮局协议(POP3)
FTP:从网络上下载文件时使用的是FTP协议,
上网浏览网页时使用的是HTTP协议,
在网络上访问一台主机时,通常不直接输入IP地址,而是输入域名,用的是DNS服务协议,它会将域名解析为IP地址,
发送邮件时,使用SMTP协议,
接收邮件时使用POP3协议

传输层协议
1.传输控制协议(TCP)
2.用户数据包协议(UDP)

网络层协议
网际协议:IP
地址解析协议APR:根据IP地址获取物理地址的一个TCP/IP协议,主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址

网站响应慢、或者无响应故障排查

堆和栈的区别:
数据结构方面
栈是后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。
堆的话是一个树型数据结构,每个结点都有一个值,通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆,常用来实现优先队列,堆的存取是随意的

内存分配中
1.申请方式和回收方式不同
栈是系统自动分配空间的,而堆则是程序员根据需要自己申请的空间。例如malloc(10)开辟十个字节的空间
栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,但是如果大量的空间被占用而得不到释放就会造成内存泄露
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

2.申请效率
栈:由系统自动分配,速度较快
堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片

3.申请大小限制
栈是向低地址扩展的数据结构,是一块连续的内存的区域。如果申请的空间超过栈的剩余空间时,将提示overflow。从栈获得的空间较小
堆:堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统

HTTP和HTTPS有什么区别
1.https协议需要到ca申请证书,一般免费的证书较少,所以证书需要购买
2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议
3.http和https使用的是完全不同的连接方式,用的端口也不一样,http是80,https是443
4.http明文传输不安全,https加密传输,相对来说较安全

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位
线程:是进程的一个执行单元,是比进程更小的独立运行的基本单位,线程也称为轻量级进程
协程:是一种比线程更轻量级的存在,一个线程也可以拥有多个协程,其执行过程更类似于子例程,或者不带返回值的函数调用

进程和线程的区别
地址空间:线程共享本进程的地址空间,而进程之间是独立的地址空间
资源:线程共享本进程的资源如内存、I/O、CPU等,不利于资源的管理和保护,而进程之间的资源时独立的,能很好的进行资源管理和保护。
健壮性:多进程要比多线程健壮,一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃会导致整个进程死掉
执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口,执行开销大
进程切换时,消耗的资源大,效率高,所以涉及到频繁的切换时,使用线程要好于进程,同样如果要求同时进行并且又要共享共享某些变量的并发操作,只能用线程不能用进程
线程是处理器调度的基本单位

协程和线程的区别
协程避免了无意义的调度,由此可以提高性能,但程序员必须自己承担调度的责任,同事,协程也失去l标准线程使用多CPU的能力
线程的切换受系统控制
协程的切换由自己控制

什么时候用多进程,什么时候用多线程
对资源的管理和保护要求高,不限制开销和效率时,使用多进程
要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程

Python装饰器的作用
装饰器本质上是一个Python函数,它可以让其他函数在不需要任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象,它经常用于有切面需求的场景,日志插入、事务处理、缓存、权限校验等。作用就是为已经存在的对象添加额外的功能

DNS域名解析
8个步骤
1.客户端通过浏览器访问域名为www.baidu.com的网站,发起查询该域名的IP地址的DNS请求。该请求发送到了本地DNS服务器上,本地DNS服务器首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,如果没有,本地DNS服务器需要向DNS根服务器进行查询
2.本地DNS服务器向根服务器发送DNS请求,请求域名的IP地址
3.根服务器经过查询,没有记录该域名及IP地址的对应关系,但是会告诉本地DNS服务器,可以到域名服务器上进行继续查询,并给出域名服务器的地址(.com服务器)
4.本地DNS服务器向.com服务器发送DNS请求,请求域名的IP地址
5…com服务器收到请求后,不会直接返回域名的IP地址的对应关系,而是告诉本地DNS服务器,该域名可以在某个域名服务器上进行解析获取IP地址,并告诉域名服务器的地址
6.本地DNS服务器向baidu.com域名服务器发送DNS请求,请求域名的IP地址
7.服务器收到请求后,把自己的缓存表中发现了该域名和IP地址的对应关系,并将IP地址返回给本地DNS服务器
8.本地DNS服务器将获取到与域名对应的IP地址返回给客户端,并将域名和IP地址的对应关系保存在缓存中,以备下次别的用户查询时使用

负载均衡策略
负载均衡是一种策略,通过重新分配系统负载,使各服务器间负载达到相对均衡,从而降低任务的响应时间,提高系统资源的利用率,使系统的性能得以提高。主要用于解决大量并发访问服务问题
策略机制:轮询、权重轮询、IP-Hash、URL-Hash、Fair
轮询:请求依次轮流分配给每个应用服务器,分配策略简单,不均匀,可能会出现,某些服务器接受的请求较重,负载压力重,某些负荷小,服务器之间需要进行session同步
权重轮询,可根据情况进行调整,可控,仍然需要进行session同步
IP-Hash:优点:无需进行session同步,固定IP会固定访问一台服务器,缺点:恶意攻击,会造成某台服务器压垮,ip可能会出现集中访问,造成不均匀,不可控
Fair:这种相当于自适应,会根据服务器处理请求的速度进行负载均衡分配。处理请求最早结束的,拿到下一个请求,看上去是不是很好。但是一般都不使用
URL-Hash:这种是根据URL进行hash,这样某些请求永远打到某台服务器,有利于利用服务器的缓存,但是可能由于URL的哈希值分布不均匀,以及业务侧重造成某些服务器压力大,某些负荷低,需要session同步
upstream site{
需要分发的服务器IP
}
server{
中转服务器地址
locathon{
proxy_pass http://site
}
}
重启nginx服务器,输入service nginx restart

Redis 支持5种数据类型:string,hash,list,set以及zset

非关系型数据库的特点
1.易扩展,数据之间没有关系
2.大数据量,高性能,高性能读写非常灵活
3.灵活的数据模型,不需要事先对存储数据建立字段
4.高可用

1.白盒测试
白盒测试用例设计:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖
黑盒测试用例设计方法:基于用户需求的测试、等价类划分法、边界值分析法、错误推测方法、因果图方法、判定表驱动分析方法、正交实验法、场景法。依据是用户需求规格说明书

软件测试的流程
1.测试需求分析阶段:阅读需求,理解需求
2.测试计划阶段:主要任务是编写测试计划,参考软件需求规格说明书,项目总体计划
3.测试设计阶段:主要是编写测试用例
4.测试执行阶段:搭建环境,执行冒烟测试-然后进入正式测试,bug管理直到测试结束
5.测试评估阶段:出测试报告,确认是否可以上线

事务的特性:原子性、一致性、隔离性、持久性
联合主键:设置多个字段同时为主键

Https证书加密的流程
1.https证书加密的第一步是认证服务器,当用户访问网站时,服务器会提供经CA机构颁发的https证书,如果认证该服务器证书的CA机构是存在于浏览器的受信任CA机构列表当中,并且https证书中的所有信息均与当前正在访问的网站所有信息一致,那么浏览器认为服务端是可信的,并从https证书中取得公钥
2.第二步协商会话秘钥,利用公钥与服务器进行加密通信,协商出两个会话秘钥,用于加密客户端和加密服务端互发数据时的会话秘钥,这个秘钥随机生成,每一次协商产生的结果都不一样,所以安全性比较高
3.第三步加密传输,当客户端和服务端都拥有协商的会话秘钥之后,进行数据传输时,都是以秘闻的方式进行传输,

找出关键字出现的次数
Grep 字符串 文件名 | wc -l

查询成绩单里两门成绩大于80的学生名字
select S.name
From Student S
Where S.score > 80
Group by S.name
Having count(*)>=2

查看当前仓库地址:git remote show origin
设置新的仓库地址:git remote set-url origin “新的仓库地址”

Python 在打开文件后为什么要close
Close是为了释放资源
如果不close,那就要等到垃圾回收时,自动释放资源,垃圾回收的时机不确定,无法控制,如果程序是一个服务,或者很长时间才能执行完,

CSRF(跨域请求伪造)
跨域请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问的一个自己曾经认证过的网站并执行一些操作,由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行,这利用了web中用户身份验证的一个漏洞,简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。可以理解为,攻击者盗用了你的身份,以你的名义发送恶意请求
解决办法
1.设置验证码
2.标志请求来源,检查是否是非正常页面过来的请求
3.token验证

持久化的实现方式. Redis提供了两种不同的持久化方法将数据保存到硬盘里面。. 快照持久化 :将Redis某一时刻存在的所有数据都写入硬盘。. AOF持久化 :AOF的全称叫append-only file,中文意思是只追加文件。. 当使用AOF持久化方式的时候,Redis执行写命令的时候,将被执行的写命令复制到硬盘里面,说的通俗一点就是写日志。

一个网页的性能有哪些指标
1.吞吐量
2.并发量
3.响应速度
4.cpu占有率和资源利用率

Linux操作系统包含4个主要部分
1.内核、shell、文件系统和应用程序

Linux内核的5个子系统
1.进程调度
2.内存管理
3.虚拟文件系统
4.网络接口
5.进程间通信

应用层:
浏览器封装 HTTP 请求报文
DNS 解析域名获得目标服务器地址
传输层:
建立TCP连接
把应用层传过来的 HTTP 请求报文进行分割,并在各个报文上打上标记序号及端口号转发给网络层
网络层:

利用 ARP 协议根据 IP 地址获取作为通信目的地的 MAC 地址后转发给链路层
服务端在链路层收到数据,按序往上层发送,一直到应用层接收到浏览器发送来的 HTTP 请求报文,然后处理该请求并返回 HTTP 响应报文,浏览器接收到响应报文之后解析渲染界面。最后 TCP 断开连接。

TCP/IP四层协议
1.数据链路层:实现网卡接口的网络驱动程序,以处理数据在物理媒介上的传输
2.网络层:实现数据包的选路和转发。
3.传输层:为两台主机上的应用程序提供端到端的通信
4.应用层:负责处理应用程序的逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值