他人面经
作者:芒果、欧尼酱
链接:https://www.nowcoder.com/discuss/490721?type=all&order=time&pos=&page=1&channel=666&source_id=search_all
来源:牛客网
一面 2020.08.27
一个大叔,起码20年开发经验,笑呵呵的
1、自我介绍
2、面向对象的三大特性
封装、继承、多态
- 封装:将数据对象和实现过程包围起来,对其内部数据的访问只能通过接口进行访问,能降低耦合性。
- 继承:子类继承父类,子类可以对父类的方法进行重写,扩充,缺点就是提高了代码的耦合性。如果一个类在定义时加上了final关键字,那么该类就不能被继承,那么其类内部的方法,不能重写,也不能对其扩充
- 多态:基类指针或者引用可以指向其不同的派生类的对象,对同一消息做出不同的反应。多态是用虚函数来实现的
3、虚函数与纯虚函数区别
定义虚函数时前面加上virtual关键字,虚函数是为了实现多态而设计的
纯虚函数在声明时前面加上virtual关键字,后面加上等于0,该类只提供接口,不提供具体实现方法,如果要定义的话,只能在类的外部定义,具体实现方法交给派生类去实现,含有纯虚函数的类称为抽象基类;不能定义抽象基类的对象,在抽象基类的派生类中必须重写纯虚函数,否则该派生类依然是抽象基类。
使用场景
4、构造函数、析构函数能否是虚函数
- 构造函数不能是虚函数
1.从存储空间的角度考虑:虚函数对应一个虚表,这个表是存储在对象的存储空间中,但是在调用构造函数是,该对象还未实例化,还没有存储空间,因此虚函数无法调用,所以说:不能将构造函数定义成虚函数
2.从使用的角度来看:虚函数是在基类指针或引用指向派生类的对象时,通过调用虚函数,实现对派生类中定义的函数的调用,而构造函数是在定义对象时,自动调用的,因此没有必要定义成虚函数。
3.从实现上来看,虚表是在构造函数调用之后才建立的,因此不能将构造函数定义成虚函数
4.在创建对象时,要明确对象的类型,而不像虚函数直到程序运行时才确定对象指向的类型 - 析构函数可以是虚函数,如果出现类的继承,在基类中一定要将虚函数定义成虚函数:
将析构函数定义成虚函数是为了避免内存泄漏,当基类对象的指针指向派生类对象时,在对该对象进行析构时,如果析构函数未定义成虚函数,只能析构基类中的成员,而派生类中特有的成员不会释放内存,从而造成内存泄漏。
5、osi七层模型 ,着重https与http
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 - http:超文本传输协议,是目前互联网上应用最为广泛的一种通信协议,是客户端和服务器端请求和应答的标准,用于服务器端将超文本传输到本地浏览器
- https:是在http的基础上,增加了传输的安全性,增加了ssl层,也就是说由http+ssl层构成,客户端和服务器端建立连接时,首先建立ssl连接
- 二者的区别:
1.传输内容:http传输的是明文,https传输的是密文
2.连接方式和端口号不同,http的默认端口号是80,https的默认端口号是443。http连接很简单,是无状态的,https是由http+ssl构成的可进行加密传输、身份认证的网络协议。
3.https需要申请ca(Certificate Authority)证书.
6、mysql与redis的区别
- mysql是关系型数据库,redis是非关系型数据库采用key-value存储方式,缓存数据库
- mysql是持久化的将数据存储在磁盘中,功能强大,支持sql语句和事务,读写速度慢;redis是频繁的将数据存储在缓存中,读写速度很快
7、mysql的连接池
在使用数据库的过程中,当出现频繁的建立连接和断开连接操作时,会使系统的性能大大降低。因此,将资源池的思想利用在数据库中,避免资源的频繁分配和释放而出现的,就出现了连接池。使得在建立连接时,调用getConnection()方法就可以获得数据库的连接,释放连接时,调用releaseConnection()方法连接池可以收回连接资源。
连接池的好处:
- 资源复用:数据库的连接得到了重用,避免了频繁建立连接和释放连接的操作,提高了系统的性能,增强了系统的平稳性。
- 提高响应速度:当连接池初始化时,建立若干数据库的连接操作,业务请求数据库时,就避免了建立连接时一系列的初始化操作,可以提高系统的性能
- 避免连接泄漏:当超过占用时间时,连接池会将占用的连接收回,避免了连接资源的泄漏
8、聚簇索引与非聚簇索引
聚簇索引:索引的顺序和数据的存储顺序是相同的,如果以新华字典举例,拼音目录就相当于聚簇索引
非聚簇索引:索引的顺序和数据的存储顺序不同,偏旁目录
索引建立的条件、问题
适合创建索引:
- 主键建立唯一索引
- 数据量非常大的时候可以建立索引
- 经常作为where查询条件的列可以建立索引
- 用来分组的列建立索引
不适合创建索引:
- 数据量小
- 属性对应的值的数量分布平均
- 经常进行插入和删除的表
- 不作为查询条件的字段
9、虚拟内存的实现
只把部分程序放到内存中,从而获得运行比物理内存更大的内存,实现内存和外存的交换,从而获得更大的内存空间。
虚拟页式存储
虚拟段式存储
10、进程通信的方式
信号、管道、消息队列、共享内存
- 管道:管道是一种半双工的通信方式,数据只能单向流动,只能在父子进程之间进行通信(匿名管道);命名管道FIFO可以在没有亲缘关系的进程之间进行通信
- 信号:信号可以在任何时候发送给某一进程而无需知道该进程的状态
11、线程安全的实现 参考:点击链接
线程安全:在拥有共享数据的多个线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程可以正确的执行,不会出现数据污染的情况
如何保证线程安全:
- 给共享资源加锁,保证每个资源变量每时每刻只能被一个线程占用
- 让线程也拥有资源,而不用去共享进程的资源,也就是说为线程维护一个私有的本地变量
12、问了一点paper的问题
13、介绍了一下趋势的业务
还有一些堆栈安全,debug与release的问题
受益匪浅
二面
1、项目介绍
2、c++当中问了好多好多啊。。。
而且问的不是基本问法,全是换个方式、场景进行提问
我被问穿了!
涉及到static(普通函数会压入一个this指针,因此static成员函数
不能访问普通成员变量),虚函数,linux文件属性
linux的namespace
mutex与临界区
子类的隐藏、重载、重写
3、socket编程
三次握手的细节
哎,还是基础不扎实。。。
三面:
1、无自我介绍
2、项目 && paper
3、三大特性
4、virtual的用法
菱形继承的原理
5、数据库的索引机制
6、写了一条sql语句
7、redis与mysql的关系
8、浏览器打不开网页的问题
dns服务器
ping的方法(localhost)
tcp的配置
9、拷贝构造函数与赋值的区别
10、两个小算法,口述
逆波兰表达式
最长回文子串
15:45-18:46
我人都面傻了 。。。。求一个oc
复盘
一面
- 介绍项目
- c++ static的使用场景
- 单例模式,饿汉模式如何实现
- 多态,如何实现?关键字
- 析构函数为什么要定义成虚函数
- 学过STL中哪些容器
- vector底层实现,push_back元素,内存会发生什么操作
- set,set中插入10个整数,遍历的时候整数的顺序怎样,set中插入n个元素的时间复杂度
二面
- 快速排序,介绍快速排序,划分点如何选取
- 红黑树,应用场景
- 8个球,其中7个重量是相同的,有一个是最重的,最少比较几次可以找到最重的这个球
- c++11的新特性
13.智能指针,使用智能指针会带来什么问题?如何解决? - 多态如何实现
- 运行时多态和编译时多态,编译时多态是如何实现的
- 进程通信方式
- https握手的过程,加密方式
- 问项目,神经网络在运行过程中会出现什么问题,过拟合和欠拟合?rnn和lstm的区别
三面
- http,和 tcp协议
- https协议,http是有状态的还是无状态的,针对这个无状态深挖
- http https
21.ttps建立连接的过程中,会建立会话密钥,然后利用网站的公钥将会话加密,并传送给网站,传送的过程当中会不会被劫持?如何防止这种现象的发生
22.ookie和session的区别 - char * a = “dddd”;和char a[] = “dddd”; 这两个变量占用多大的内存空间,变量存储的位置,“dddd”存储的位置
- c++多态的使用场景
- static_cast, reinterpret_cast, dynamic_cast的区别
- 归并排序的使用场景
- 抢占式调度和非抢占式调度,windows系统是哪种调度方式(抢占式调度)