面经笔记总结
【编程语言】
1.内存泄漏和溢出
内存泄漏:
程序在申请内存后,无法释放已经申请的内存空间
无用对象持续占有内存 或者长时间未被释放
1.常发性内存泄露:
发生内存泄漏的代码被多次执行,每次被执行的时候都会导致一块内存的泄露
2.偶发性内存泄露:
发生内存泄露的代码只在某个特殊环境或操作过程执行
3.一次性内存泄漏:
发生内存泄漏的代码只被执行了一次
(例如在建立对象时用new开辟了一片内存空间,析构函数后释放内存)
4.隐式内存泄漏:
程序在运行过程中不停的分配内存,直到快结束的时候内存才分配好
内存溢出
程序在申请内存的时候,没有足够的内存空间供开发者使用,内存泄漏堆积后会造成内存溢出。
1.永久保存区溢出:
java里的GC不会在主程序运行期对永久保存区进行清理,当程序启动时候如加载的信息过多,超过这个空间的大小,就会发生溢出。
1.Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法
2.永久保存区,该块内存主要是被JVM用来存放class和mete信息的
解决方案:增加空间分配
2.堆区溢出:
当建的对象太多超出空间大小,GC又来不及释放,就会发生溢出错误,也就是内存泄露越来越严重的时候,就会发生内存溢出。
解决方案:检查程序,减少重复创建对象的死循环,减耗内存泄露,增加java虚拟机中初始堆和最大堆参数的大小。
3.栈区溢出:
栈区主要是用来存放方法的变量、参数等临时数据,发生溢出一般是因为分配空间太小,或者执行的方法递归层数太多。
解决方案:增加线程栈的大小,优化程序
2.堆和栈的区别
stack:先进后出,内存在申请之后不会发生变化,这些内存会由操作系统自动释放。
局部变量、一些基本数据类型都会被存放在栈中。
heap:相比于栈的固定,堆分配相对自由,并且不要求连续的内存,只要有空间分配就行,不过这会导致产生很多碎片,不利用高速读取。
数组,结构体这些大小不固定的内存结构经常被存放在堆中,全局变量也存放在堆中。
3.抽象类和接口
抽象类:
在面向对象的概念中,所有对象都是通过类来描述的,但并不是所有类都是用来描述对象的。
如果一个类中没有足够的信息来描述一个具体的对象,这样的类就是抽象类。
抽象类不能实例化对象,必须被继承才能使用。
接口
接口是对类的延伸,是对类的描述。
抽象类与接口的比较
是否多继承:一个子类只能继承一个抽象类 但是可以继承多个接口。
继承方式:子类继承(extends)抽象类(abstract),子类使用Implements实现接口
构造器:抽象类有构造器,接口没有构造器
修饰符:抽象类可以使用public/protected/default等修饰符,接口默认是public访问修饰符,并且不能使用其他修饰符
4.进程和线程
进程:进程是程序的一次动态执行,是系统资源分配和调度的基本单位。
线程:线程是程序运行的执行单元,依托于进程
一个进程可以包含多个线程,多线程可以共享一块内存空间和一组系统资源。
进程之间是独立的,线程是进程中执行的一段程序片段。
线程占用的资源比进程少
进程的调度算法:
先来先去服务、时间片轮转法、短作业优先、多级反馈队列调度算法、优先级调度
5.常用的Linux命令
pwd 显示当前所在的位置
sudo+其他命令 使用系统管理者的身份执行指令
grep 要搜索的文件、字符串
ps -ef 查看系统当前正在运行的进程,在后面加 |grep就能查看到特定的进程
wget 远程下载
free 显示系统内存使用情况
vmstat 虚拟内存性能监控 cpu监控
6.死锁
两个或者两个以上的进程在执行过程中,争夺资源而造成的一种互相等待现象
产生原因:
(1)系统资源不足
(2)进程运行推进的顺序不合适
(3)资源分配不当
产生的四个必要条件
(1)互斥条件:一个资源每次只能被一个进程中使用
(2)占有且等待:一个进程因为请求资源而阻塞时,对已获得的资源保持不放
(3)不可强行占有:进程已获得的资源在未使用完之前,不可强行剥夺
(4)循环等待条件:若干进程之间形成一种头尾相连的循环等待资源关系
解决方案:
(1)死锁预防:破坏条件中的一个或几个
(2)死锁避免:允许前三个必要条件,但通过明智的选择,确保永远不会到达死锁点
(3)死锁检测:不采取限制措施,通过检测精准定位将其清除掉
(4)死锁解除:与死锁检测配套,常用方法是撤销或者挂起一些进程,以便回收一些资源进行分配
银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
7.聚合函数
定义:
聚合函数是SQL基本函数,对一组值执行计算,并返回单个值,也被称为组函数。常与SELECT语句的GROUP BY字句的HAVING一同使用。
除COUNT外,聚合函数忽略空值,如果COUNT函数的应用对象是一个确定列名,并且该列存在空值,此时COUNT仍会忽略空值
不使用聚合函数的时候,group by子句必须包含所有的列,否则会报错
在子句加上所有列的时候
此时虽然成功执行了,但是可以看出来group by在这里并没有发挥任何的作用,我们完全可以直接select而不用group by,所以,group by子句要配合聚合函数使用,并且,在配合聚合函数使用的时候,在group by子句中不要加上聚合函数处的列名(加入as了的话)
【计算机网络】
1.网络协议——七层、五层、四层协议概念及功能分析
2.TCP和UDP高频面试题
1.UDP与TCP的特点和区别:
UDP: 用户数据报协议 user datagram protocol
无连接 ,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信
TCP:传输控制协议 transmission control protocol
面向连接,提供可靠交付,有流量控制,拥塞控制,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条TCP连接只能是点对点的(一对一)。
2.TCP的第三次握手和第四次挥手
TCP——SYN、ACK、FIN、RST、PSH、URG详解
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
确保最后一个确认报文能够到达。如果 服务端 没收到 客户端发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
3.TCP短连接和长连接的区别
短连接:客户端给服务端发送消息,服务端回应客户端,然后一次读写就完成了,这时候双方都可以发起close操作,不过一般都是客户端先发起close操作。短连接一般只会在client/server之间传递一次读写操作。
短连接优点: 管理起来比较简单,建立起来的连接都是有用连接,不需要额外的控制手段。
长连接:客户端和服务端完成一次读写操作后,它们之间的连接不会主动关闭,后续的读写操作会继续使用这个连接。
在长连接的应用场景下,客户端一般不会主动关闭它们之间的连接,客户端与服务端之间的连接的如果长时间不关闭,随着客户端连接越来越多,服务器压力也会越来越大,这时候服务端需要采取策略,比如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连 接导致服务端服务受损;如果条件再允许可以以客户端为颗粒度,限制每个客户端的最大长连接数,从而避免某个客户端连累后端的服务。
4.TCP粘包、拆包以及解决办法
(1)为什么常说TCP有粘包和拆包问题不说UDP
因为UDP是基于报文发送的,UDP首部采用了16bit来指示UDP数据报文的长度,因为在应用层可以很好地将不同数据报文区分开,从而避免粘包和拆包问题。
TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP并没有把这些数据块区分边界,仅仅是一连串没有结构的字节流;从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段,基于上面两点,在使用TCP传输数据时,才会有粘包或者拆包现象发生的可能。
(2)什么是粘包、拆包?
(3)为什么会发生TCP粘包、拆包
要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。
接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包
(4) 粘包、拆包的解决办法
TCP本身是面向字节流的,无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的。
所以这个问题只能通过上层的应用协议栈设计来解决:
- 消息定长:发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
- 设置消息边界:服务端从网络流中按消息边界分离出消息内容。在包尾增加回车换行符进行分割,例如 FTP 协议。
- 将消息分为消息头和消息体:消息头中包含表示消息总长度(或者消息体长度)的字段。
- 更复杂的应用层协议比如 Netty 中实现的一些协议都对粘包、拆包做了很好的处理。
5.TCP可靠传输
TCP使用消息重传来实现可靠传输:如果一个已近发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。
6.TCP滑动窗口
7.TCP流量控制
为了控制发送方发送速率,保证接收方来得及接收
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。
8.拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高,因此当出现拥塞时,应当控制发送方的速率。主要通过慢开始,拥塞避免,快重传,快恢复。
3.HTTP和HTTPS
HTTP:
HTTP即超文本传输协议,是web的应用层协议。一个客户程序一个服务器程序,客户程序和服务程序运行在不同的端系统中,通过交换HTTP报文进行会话。HTTP使用TCP作为它的支撑运输协议,HTTP是一种无状态的协议,默认端口是80。
HTTPS:
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL,端口默认是443。HTTPS的传输过程主要分为两部分:通过SSL握手建立安全的HTTPS通道和在安全的通道上进行数据传输。
区别:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
(2)HTTP存在的问题:
a.HTTP没有密码加密,无法保证通信内容不被窃听,攻击者可以截取客户发送的数据并得到他的信息。
b.HTTP没有报文完整性验证,无法确保通信内容在传递过程中不被改变,攻击者可以篡改客户通信内容。
c.HTTP没有身份鉴别,无法让通信双方确认对方的身份,攻击者可以伪装成客户或者服务器。
(3)非持续连接和持续连接
依据每个请求/响应对经过一个单独的TCP连接还是相同的TCP连接发送,划分成为非持续性连接和持续性连接。HTTP默认使用持续连接,但是可以配置成使用非持续连接
非持续连接的步骤
持续连接的缺点
4.Cookie
Cookie是一种客户端的会话技术,允许站点对用户进行追踪。
(1)Cookie的四个组件:
在HTTP响应报文中的一个cookie首部行
在HTTP请求报文中的一个cookie首部行
在用户端系统中保留有一个cookie文件,并由用户的浏览器关联
位于WEB站点的一个后端数据库
(2)Cookie的工作流程
当客户通过浏览器第一次访问某一个站点时,该web站点产生一个唯一的识别码,并以此作为索引在它后端的数据库中产生一个表项,接下来服务器会用一个包含Set-cookie首部的HTTP响应报文对浏览器进行响应,当浏览器收到后将其添加到自己管理的cookie文件中,在下次访问该站点时,请求报文的首部行中就会包含这个识别码,尽管浏览器不知道客户是谁,但是可以确认是同一个客户进行访问。
(3)session与cookie的区别
两者都是用来跟踪浏览器用户身份的会话方式
a.cookie用来保存用户信息,session通过服务端记录用户状态
b.cookie只能存储ASCⅡ字符串,而session可以存储任何类型的数据,因此在考虑数据复杂性时首选session
c.session存储在服务器,cookie存储在客户浏览器,容易被恶意查看,。
如果要存入隐私数据在cookie,可以先将cookie值进行加密,然后在服务器进行解密。
Cookie被禁用:利用URL把sessionID直接附加到URL路径的后面
(4)WEB缓存器
WEB缓存器也叫代理服务器,能够代表初始web服务器来满足HTTP请求的网络实体。
WEB缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象副本。
(5)客户通过web缓存器请求对象的步骤:
(1)浏览器创建一个到web缓存器的TCP连接,并向web缓存器中的对象发送一个HTTP请求
(2)web缓存器进行检查,查看本地是否存储了该对象的副本。如果有,web缓存器就向客户浏览器用HTTP响应报文返回该对象。
(3)如果web缓存器没有该对象,它就打开一个与该对象的初始服务器的TCP连接,web缓存器在这个连接上发送一个请求并接受响应
(4)web缓存器收到响应后,在本地存储空间存储一份副本,并向客户的浏览器用HTTP响应报文发送该副本
WEB缓存器的作用(部署原因)
(1)Web缓存器可以大大减少对客户请求的响应时间,特别是客户与初始服务器之前的带宽远低于客户与web缓存器之间的带宽时。
(2)Web缓存器可以大大减少一个机构的接入链路到因特网的通信量,通过减少通信量,机构不必基于增加带宽,可以降低费用。
(6)Get和Post
Get和Post是http请求的两种基本方法:
- 请求缓存:GET 会被缓存,而post不会
- 收藏书签:GET可以,而POST不能
- 安全性:post比get安全
- 保留浏览器历史记录:GET可以,而POST不能
- 用处:get常用于取回数据,post用于提交数据
【数据库】
1.常用的sql优化方式
(1)使用select时尽量不要使用*,会增加不必要的消耗;增加了使用覆盖索引的可能性,当表结构发生改变时,前断也需要更新,所以直接在select后面加字段名。
(2)创建索引,尽量避免全局扫描,避免在索引上使用计算,这样会使索引失效
(3)用where代替having,并调整where字句里面的连接顺序
1、select语句汇总,where字句过滤行
2、having字句是分组后才过滤
3、行被分组需要时间,降低分组的行数可以提高效率,所以使用where 字句代替havingz字句
(4)尽量将多条sql语句压缩到一句sql中
(5)使用update时如果只更新几个字段就不要更新全部
(6)创建临时表时,如果数量很大,用select into代替create table,如果数据量不大,先create table再insert
(7)使用最简单的数据类型,尽量少使用text,适当分表,分库
2.什么情况下索引会失效 *
(1)引进了表达式计算
(2)使用了函数
(3)where里,如果在or前面的条件使用索引,or后的没有使用
(4)使用like进行模糊查询时候,后面不能是%
(5)索引列与NULL或者not NULL进行判断时
3.MySQL执行一条查询语句的内部执行过程
(1)客户端先通过连接器连接到MySQL服务器
(2)连接器权限验证通过后,先查询是否有查询缓存,如果有直接返回缓存数据,如果没有进入分析器
(3)分析器会对查询语句进行语法分析和词法分析,若正确则进入优化器
(4)优化器对查询语句进行优化处理
(5)优化器执行完进入执行器,执行器则开始执行语句进行查询对比对,知道查询到满足条件的所有数据,然后进行返回
4.MySQL查询缓存的优缺点
MySQL查询缓存是在连接器之后发生的,效率极高,如果有则直接返回结果。
但是失效太频繁会导致缓存命中率比较低,任何更新表操作都会清空查询缓存。
5.MySQL事物
a.事务四个特性【 ACID 】
( 原子性 一致性 隔离性 持久性)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
b.事务的并发问题
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
c.MySQL里几种事务的隔离级别
d.全局锁
对整个数据库实例加锁,典型场景是做全量逻辑备份。使用全局锁会使整个系统不能执行更新操作。
事务隔离级别为串行化时,读写数据都会锁住整张表
6.数据库的创建和删除
create database
drop database