本文是记录平常看到的面试八股文问题,其问题主要是从leetcode中的讨论区整理出来的,答案大多是参考一些大佬讲解来整理的,在此进行整理,方便大家换工作时来熟悉下常见的八股文问题。大家可以看看,也可以讨论下:
//2021.05.10
微信|后端开发|面经(21届秋招)|2021|
1、腾讯面试题:寻找一个长度为n+1,且值为1~n的数组中相同的两个元素最优算法
(1)数学加法
(2)异或
腾讯面试题:寻找一个长度为n+1,且值为1~n的数组中相同的两个元素最优算法_zarro brain的博客-CSDN博客
2、malloc和new有以下区别:
(1)new,delete是操作符,只能在C++中使用;
(2)malloc,free是函数,可以覆盖,C,C++中都可以使用;
(3)new可以调用对象的构造函数,对应的delete调用相应的析构函数;
(4)malloc仅仅分配内存,free仅仅回收内存,并不执行构造和析构函数;
(5) malloc/free需要手动计算类型大小且返回值为void*,new/delete可自己计算对应类型的大小。
(6)malloc/free申请空间后得判空,new/delete则不需要。
(7) new直接跟类型,malloc跟字节数个数。
(8)new/delete的底层调用了malloc/free
3、java中new关键字和c++中的new
(1)java中new返回的对像引用,而c++中返回的是对像的实际地址。
没有delete的原因是java有垃圾回收机制,当一个对像没有被引用时,系统会自动将其清理掉(也就是系统自动执行了delete)
4、java中的内存回收机制
(1)
内存泄露:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
内存溢出:指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,
那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出。
(2)
Java 垃圾回收机制原理_wuzhixiu007的博客-CSDN博客_java垃圾回收机制原理
垃圾回收算法需要做的基本事情:
1)发现无用对象
1.1 引用计数法
1.2 根搜索算法
2)回收被无用对象占用的内存空间,使该空间可被程序再次使用
2.1 标记-清除(Mark-Sweep)算法
2.2 复制(Copying)算法
2.3 标记-整理(Mark-Compact)算法
2.4 分代收集(Generational Collection)算法:
分代收集算法是目前大部分 JVM 的垃圾收集器采用的算法。
核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),
老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法
5、为什么进程切换会比线程切换消耗的资源要多?
进程切换与线程切换的代价比较_c_雨山的博客-CSDN博客_进程间切换比线程间切换开销大
进程切换分两步:
1).切换页目录以使用新的地址空间
2).切换内核栈和硬件上下文
对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。
切换的性能消耗:
(1)、线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。
内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。
(2)、另外一个隐藏的损耗是上下文的切换会扰乱处理器的缓存机制。简单的说,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。还有一个显著的区别是当你改变虚拟内存空间的时候,
处理的页表缓冲(processor's Translation Lookaside Buffer (TLB))或者相当的神马东西会被全部刷新,这将导致内存的访问在一段时间内相当的低效。但是在线程的切换中,不会出现这个问题。
6、select、poll、epoll之间的区别
select、poll、epoll之间的区别(搜狗面试) - aspirant - 博客园
(1)select==>时间复杂度O(n)
它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。
所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。
(2)poll==>时间复杂度O(n)
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的.
(3)epoll==>时间复杂度O(1)
epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,
此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))
select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,
异步I/O的实现会负责把数据从内核拷贝到用户空间。
7、 两个进程分别监听 TCP 和 UDP,可以监听同一个端口?
TCP和UDP可以同时监听相同的端口吗_程序员面试之道的博客-CSDN博客_udp和tcp同时监听一个端口
答:可以,linux是以协议、ip、端口来绑定端口的,所以不同协议相同的ip和端口也是可以绑定成功的
8、Web 页面请求过程(URL请求过程)
浏览器中输入URL,首先浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,如果没有就给本地DNS发送查询请求。DNS查询分为两种方式,
一种是递归查询,一种是迭代查询。如果是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,
然后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。得到IP地址后,浏览器就要与服务器建立一个http连接。因此要用到http协议,http协议报文格式上面已经提到。
http生成一个get请求报文,将该报文传给TCP层处理。如果采用https还会先对http数据进行加密。TCP层如果有需要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包然后会发送给IP层,
用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP,SLIP),以太网协议需要直到目的IP地址的物理地址,
有需要ARP协议。
//2021.05.12
1、C++中的观察者模式
(1)观察者模式:
是讲有一个目标,众多个观察者去“观察”目标。目标是目标抽象类的一个派生类,观察者是观察者抽象类的一个派生类。当目标类的数据改变,所有对应的观察者对应去更新自己的状态。
注意观察者处于被动地位,被观察者处理主动地位。
(2)应用场景
比如有一个世界时钟程序,有多个图形时钟去显示比如北京时区&#x