面试问题汇总(持续更新)

目录

深度学习方面

卷积尺寸?计算量?参数数量?感受野?(*)

输出特征图尺寸:n’ * n’ * c’,n’ = (n+2p-k)/s+1 (向下取整)
计算量:总乘法/总加法次数=(k * k * c )* (n’ * n’ * c’)
参数数量:w个数:k * k * c * c’;b个数:c’
感受野:令n’=1,倒推n
k:卷积核尺寸
n:输入特征图尺寸
n‘:输出特征图尺寸
c:输入特征图通道数
c’:输出特征图通道数/卷积核个数

卷积的变种?

分组卷积(Group Convolution)
空洞(扩张)卷积(Dilated/Atrous Convolution)
深度可分离卷积(depthwise separable convolution)
可变形卷积网络(Deformable Convolution)
反卷积(deconvolution)
图卷积(Graph Convolution)
X-卷积(PointCNN);

过拟合怎么办?(*)

  1. 增加/清洗数据
    (1)增加数据量,减少特征维度
    数据扩充,数据合成(减少噪声比重)
    (2)清洗数据
    (3)其他
    每个epoch后shuffle数据(烤鱼,多次2面翻烤,鲁棒)
    加BN(降低batch内样本分布差异,但也同时允许有自己的分布)

  2. 减小模型复杂度
    (1)减少神经元个数,网络层数
    (2)增加正则化项
    (3)dropout(随机失活)
    (4)early-stopping(在验证集误差最小时,停止训练)
    (5)bagging集成学习(降低单一模型过拟合风险)

  3. 调整超参
    (1)增大学习率α
    (2)减少迭代次数
    (3)增加噪声

样本不均衡怎么办?

(1)样本多的类别,下采样
(2)样本少的类别,上采样
(3)设置阈值

检测任务中不均衡解决办法:
1.online hard example mining(OHEM);
2.Focal Loss;
3.class balanced cross-entropy;
4.local rank,PISA,ISR;
5.过采样;

BN原理和作用?测试时怎么用?(*)

  • 原理:将一个batch的数据变换到,均值为0,方差为1的正态分布上
  • 作用:使得数据分布一致,每层的梯度不会随着网络层数增加而发生太大变化, 避免发生梯度消失,加快收敛,防止过拟合
  • 测试:用训练阶段的均值,方差,作为测试样本的均值和方差
    面试问题汇总(持续更新)

梯度消失?梯度爆炸?梯度弥散?(*)

TODO

介绍droppout?为什么可以防止过拟合?(*)

Dropout 是指在模型训练时随机让网络某些隐含层节点的权重不工作,不工作的那些节点可以暂时认为不是网络结构的一部分,但是它的权重得保留下来(只是暂时不更新而已),用于防止模型过拟合。

防止参数过分依赖训练数据,减少神经元之间复杂的共适应关系,增加参数对数据集的泛化能力。

优化方法

定义:在模型空间中找到在模型评估指标上表现最好的模型,加快网络训练
(1)GD
(2)SGD
原理:用单个样本的损失近似平均损失,计算梯度,适用于小样本
不足:每次更新只用一个样本,信息量有限,估计方差大,容易陷入山谷震荡,和鞍点停滞,导致收敛不稳定或者不收敛
(3)BGD
(4)Momentum
为了获得惯性保持,当前梯度计算会考虑之前的梯度,但是之前的梯度会做一定程度的衰减
(5)Adagrad
为了获得环境感知,自适应调整学习率,当前学习率和之前梯度的模成反比。存在有效学习率过早或过量减小
(6)Adam
为了获得惯性保持和环境感知,分别计算梯度的一阶矩(之前梯度和当前梯度的平均)和二阶矩(之前梯度平方和当前梯度平方的平均)

传统迭代法
x_(n+1)= x_n - f(x_n)) /(f’(x_n) f(x) = f(x_0 ) + (x-x_0 )f’(x_0)
x_(n+1)= x_n - f’(x_n))/(f’’(x_n) f(x) = f(x_0 ) + (x-x_0 ) f’ (x_0 )+1/2 (x-x_0 )^2 f’’(x_0)

L1和L2正则的特点?

L1 L2
分布 拉普拉斯 高斯
目的 限制参数过多或者过大,避免模型更加复杂
适用 模型中有很多相关特征,用L1消除共线性问题 样本足够多,用L2防止过拟合

**函数优缺点?(*)

面试问题汇总(持续更新)

  • 特性:
    定义域:(-∞,+∞) ;值域:(0,1)
    在定义域内,是连续、光滑的函数,处处可导,导数为 f’(x) = f(x)*(1-f(x))
  • 优点:
    (1)实现非线性变换
    (2)梯度容易计算
    (3)可以进行数据压缩
  • 缺点:
    双边饱和,易出现梯度消失
    幂运算耗时
    输出均值非0

面试问题汇总(持续更新)

  • 特性:
    定义域:(-∞,+∞);值域:(-1,1)
    在定义域内,是连续、光滑的函数,处处可导,导数为 f’(x) =1-f2(x)

  • 优点:
    (1)实现非线性变换
    (2)梯度容易计算
    (3)可以进行数据压缩
    (4)近0处,梯度比sigmoid大,收敛快
    (5)输出均值为0,数据中心化

  • 缺点:
    双边饱和,易出现梯度消失
    幂运算相对耗时
    面试问题汇总(持续更新)

  • 特性:
    定义域:(-∞,+∞);值域:[0,+∞)
    在定义域内,是连续的函数,在(0,0)不可导,其他地方导数为 f’(x) =max(0,1)

  • 优点:
    (1)实现非线性变换
    (2)梯度容易计算,比sigmoid和tanh简单
    (3)z>0的区域,不会梯度消失
    (4)保留了输入信息

  • 缺点:
    z<0的区域,出现梯度弥散,神经元死亡
    均值非0

**函数改进?

面试问题汇总(持续更新)

初始化方法

权重初始化: w不为0,不饱和

(1)高斯分布
面试问题汇总(持续更新)

(2)均匀分布
面试问题汇总(持续更新)

(3)Xavier(Glorot)
面试问题汇总(持续更新)
(3)He
面试问题汇总(持续更新)

卷积核为什么是奇数?

关于中间像素点中心对称

怎么增大感受野?

(1)将原始图像的尺寸resize得更大
(2)增大网络层数
(3)池化
(4)增大卷积核尺寸
(5)增加卷积核个数
(6)增大步幅
(7)空洞(dilated)卷积

决策树怎么选择特征?

(1)信息增益
(2)信息增益比
(3)gini指数

LSTM介绍?(*)

GAN损失函数?(*)

为什么LSTM后面接CRF更好

https://blog.****.net/SIGAI_****/article/details/82804107

归一化方式?

面试问题汇总(持续更新)

聚类算法,评价方法,优化算法

**函数如何引入非线性?证明引入非线性,为何就可以说这个网络可以表示几乎所有的连续函数?

word2vec原理,优化

bert,位置向量作用,生成方式

k-mean和k-NN的区别,优缺点,改善

HMM

NB和B的区别

LR和SVM的区别

RF和Xgboost的区别

Jacobian和Hessian

Jacobian矩阵:一阶偏导矩阵
Hessian矩阵:二阶偏导矩阵

强化学习

model-based:对环境建模,在执行动作之前,可以预测下一步的状态和回报
model-free:不对环境建模,在执行动作之前,不能预测下一步的状态和回报

value-based(Q-learning):求状态价值函数V和状态动作价值函数Q
(1)适用于动作空间是低维离散的情况
(2)计算每个A的价值
(3)每个A都更新
policy-gradient(Reinforce):对策略进行参数化表示,简单,易收敛
(1)不受动作空间限制,可以处理连续动作
(2)只给出价值较高的A
(3)一个epoch更新1次
(4)不能保证最优解,方差大

python方面

python和c++的区别?

python是强类型语言,不需要变量声明 ;C++是强类型语言,需要变量声明
python是解释型脚本语言;C++是编译型语言
python编程简单,效率低;编程较难,效率高
python能自动回收内存;C++需要手动回收内存

python怎么回收内存?

(1)当对象不再被引用指向的时候,垃圾收集器可以释放该对象;
(2)手动回收:gc.collect();

python为什么慢?

(1)有GIL:多线程,1次只能用1个核
(2)解释型语言:虚拟机解释opcode过程慢,需要先编译成中间代码,再翻译成CPU可理解的指令
(3)动态类型语言:不需要变量声明,检查、改变类型开销大

tensorflow底层

装饰器(*)

单例模式(*)

概念:
(1)一个类,只有一个实例,支持全局访问(接口)
(2)构造函数是私有的(静态特性,禁止用户自己声明、定义实例)
实现方式:
(1)懒汉式——使用时实例化,不浪费内存,线程安全;使用同步锁,效率低
(2)饿汉式——线程安全;类加载时实例化,占额外内存
(3)双重检查式——效率高,保证线程安全
(4)静态内部类——调用内部类时实例化,不占额外内存,线程安全,效率高
(5)枚举方式
(单例模式,可以被继承,但其派生类,依旧不能生成实例)
优点:
(1)减少内存开销,尤其是频繁的创建和销毁实例;
(2)避免对资源对过多占用
缺点:
(1)没有抽象层,不能继承,扩展很难
(2)违背了“单一职责原则”,一个类只重视内部关系,而忽略外部关系。
(3)不适用于变化对象。
(4)滥用单例会出现一些负面问题,如为节省资源将数据库连接池对象设计为单例,可能会导致共享连接池对象对程序过多而出现连接池溢出。如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这样将导致对象状态丢失。
应用:
(1)统计当前在线人数(网站计数器):用一个全局对象来记录。
(2)打印机(设备管理器):当有两台打印机,在输出同一个文件的时候只一台打印机进行输出。
(3)数据库连接池(控制资源):一般是采用单例模式,因为数据库连接是一种连接数据库资源,不易频繁创建和销毁。
(数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率的损耗还是非常昂贵的,因此用单例模式来维护,就可以大大降低这种损耗。)
(4)应用程序的日志(资源共享):一般日志内容是共享操作,需要在后面不断写入内容所以通常单例设计。

self关键字的作用

对象传递,类内方法互相调用

pass语句的作用

占位,不做任何事情

with关键字的作用

With open(‘file.txt’) as f
进入上下文,返回一个对象,被f引用

下划线的区别和意义

单前导下划线:

_var # 半私有,可被外部访问

单末尾下划线:

var_ # 避免命名冲突

双前导下划线:

__var # 私有,不可以被外部访问

双前导和末尾下划线:

var # 魔术方法,内置属性名

单下划线:

_ # 临时/无关紧要的变量

列表去重

List.fromkeys() # 得到的不重复数字是列表的键
Set
For函数遍历

python调试方法

(1) 创建断点,运行,单步运行
(2) @pysnooper.snoop()
(3) Python -mtrace –trace test.py
(4) Python -mpdb test.py

c++方面

多态(*)

不同的响应
重载多态:函数、运算符
子类型多态:虚函数
参数多态:(类/函数)模板
强制多态:(基本/自定义)类型转换

虚函数(*)

前面有virtual关键字的成员函数,在基类中实现
为了被派生类重写,也可以不重写

纯虚函数:基类中,只做声明,不做实现,实现由派生类做

三个关键字的访问权限,继承权限

Private:类内访问,类外不行
Protected:类内访问,类外不行
Public:类内,类外访问
面试问题汇总(持续更新)
私有继承:原public和protected都变成private,原priate不可访问
保护继承:原public变成protected,原priate不可访问
公有继承:保持不变
面试问题汇总(持续更新)

static(*)

(1) 普变:存静态区,运行前分配空间,初始化(默认或赋值)
(2) 普函:限定作用范围,只能在文件内使用,防止和别人代码重名
创建独立于对象的变量/方法,不用生成变量就能访问
(3) 成变:所有对象只保存一个该变量
(4) 成函数:static函数内不能访问非静态成员
实现:当程序被装载进内存,所有static完成初始化,存在全局变量区,变量只有这一格,不会被回收

抽象

带纯虚函数(基类声明,派生类实现)的类——抽象类
抽象类,不能生成对象,只能被继承,重写虚函数后,可以使用

new和malloc的区别

New:底层调用malloc分配内存(自动计算字节数),调用构造函数
Malloc:申请指定字节数的内存(手动输入字节数),初始值不确定

栈?堆?栈和堆?

栈=外食,快捷,自由度小(线程私有)
(1)自动分配空间,速度快,成员无法控制
(2)向下生长
(3)x86下默认1M
(4)先进先出,管理方便
堆=自己做,麻烦,自由度大(进程共用)
(1)速度慢,产生碎片
(2)向上生长
(3)x86下将近2.5G
(4)链表结构,申请,回收麻烦

c++内存分配方式

(1) 栈:函数内局变,结束自动释放,内存分配在处理器指令集中
(2) 堆:new分配的内存块,对应delete,自动释放
(3) 自由存储区:malloc分配的内存块,对应free
(4) 全局/静态存储区:全局变,静态变,存在一块内存中
(5) 常量存储区:存常量,不能改

指针和引用

内存管理单元的作用

构造函数,析构函数

链表与线性表

类型转换

指令流水

数据结构

算法方面

判断链表是否有环

查找第k大数

旋转数组找最大值

1~n中1的个数

原地奇数在前,偶数在后

手写链表

给出前序、中序,重建二叉树

数学方面

x,y 服从 0−1 均匀分布,求 x+y<1 的概率?x,y,z 服从 0−1均匀分布,求x+y+z<1 的概率?

P(x+y<1)=1/2
P(x+y+z<1)=1/3

linux方面

查看cpu使用情况?

top
计算文件中所有jpg图片的数量
ls -l |grep “jpg”|wc -l

多线程?同步方式?

同步方式:
(1) 互斥锁:同时,1线程,1关键代码(初始化,加锁,解锁,清除锁)
(2) 条件变量:初始化,等待条件,**条件,清除条件
(3) 信号量

虚拟内存?

定义:扩充内存的存储系统,有请求调入、置换2功能。
解决:多进程,操作内存,冲突问题
其他:Cpu快,但小,功能单一;I/o硬件功能多,但慢

每一条对照,要8Byte,4G内存,需要32GB空间存放对照表,太大,引入页
页:将物理内存,以4k为单位,划分成大小相等的物理块
段:将物理内存,划分成大小不等的物理块

页:大小固定,信息的物理单位,空间地址是1维的
段:大小不定,信息的逻辑单位,空间地址2维的
面试问题汇总(持续更新)

内核态用户态转换

两者通信方式有4种:
(1)syscall:一般情况下,用户进程是不能访问内核的。它既不能访问内核所在的内存空间,也不能调用内核中的函数。Linux内核中设置了一组用于实现各种系统功能的子程序,用户可以通过调用他们访问linux内核的数据和函数,这些系统调用接口(SCI)称为系统调用;
(2)procfs:是一种特殊的伪文件系统 ,是Linux内核信息的抽象文件接口,大量内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样我们就可以简单直接的通过echo或cat这样的文件操作命令对系统信息进行查取;
(3)netlink:用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能;
(4)ioctl:函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。

linux目录结构

面试问题汇总(持续更新)
•/usr:不是user的缩写,其实usr是Unix Software Resource的缩写, 也就是Unix操作系统软件资源所放置的目录,而不是用户的数据啦。这点要注意。 FHS建议所有软件开发者,应该将他们的数据合理的分别放置到这个目录下的次目录,而不要自行建立该软件自己独立的目录;
•/tmp:这是让一般使用者或者是正在执行的程序暂时放置档案的地方。这个目录是任何人都能够存取的,所以你需要定期的清理一下。当然,重要资料不可放置在此目录啊。 因为FHS甚至建议在开机时,应该要将/tmp下的资料都删除;
•/etc:系统主要的设定档几乎都放置在这个目录内,例如人员的帐号密码档、各种服务的启始档等等。 一般来说,这个目录下的各档案属性是可以让一般使用者查阅的,但是只有root有权力修改。 FHS建议不要放置可执行档(binary)在这个目录中。 比较重要的档案有:/etc/inittab, /etc/init.d/, /etc/modprobe.conf, /etc/X11/, /etc/fstab, /etc/sysconfig/等等。

网络方面

HTTP与HTTPS?

HTTP:明文传输,端口80,无状态连接(数据包的发送、传输和接收都是相互独立的)
HTTPS:SSL加密传输,端口443,SSL+HTTP加密传输、身份认证
面试问题汇总(持续更新)

TCP与UDP?

TCP:面向连接,可靠,字节流
一对一,全双工,拥塞控制
首部开销20字节
UDP:无连接,不可靠,面向报文
一/多对一/多,不可靠信道,无拥塞控制
首部开销8字节
面试问题汇总(持续更新)

TCP为什么要3次握手?

因为信道不可靠,而 TCP 想在不可靠信道上建立可靠地传输,双方都需要确认对方收到了自己发送的***,确认过程最少要进行三次通信。(而 UDP 则不需建立可靠传输,因此 UDP 不需要三次握手。)
握1:客户端调用 connect 时,向服务器发送 SYN J,请求建立连接,这时 connect 进入阻塞状态;
握2:服务器收到请求SYN J,调用 accept 函数,并发送ACK J+1 和 SYN K,同意建立连接,这时 accept 进入阻塞状态;
握3:客户端收到ACK J+1 和 SYN K,这时 connect 返回,回复服务器ACK K+1,
服务器收到ACK K+1 时,accept 返回连接建立,可以数据传输
面试问题汇总(持续更新)

TCP为什么要4次挥手?

因为 TCP 是全双工模式,客户端请求关闭连接后,客户端向服务端的连接关闭(一二次挥手),服务端继续传输之前没传完的数据给客户端(数据传输),服务端向客户端的连接关闭(三四次挥手)。
(1)客户端发送 FIN 给服务器,告知不再发送数据了(请求释放C—S连接);
(2)服务器收到FIN,并回复 ACK ,表示同意(同意释放C—S连接);
(3)客户端收到ACK,此时从C—S连接已释放(但服务端到客户端的连接还未释放,并且客户端还可以接收数据);
(4)服务端继续发送之前没发完的数据给客户端;
(5)服务端发送 FIN+ACK 给客户端,告知不再发送数据(请求释放S-C连接,就算没收到客户端的回复,过段时间也会自动释放);
(6)客户端FIN+ACK,并回复 ACK,表示同意(同意释放从服务端到客户端的连接);
(7)服务端收到ACK 后,释放从S-C的连接。
面试问题汇总(持续更新)

socket中TCP 的四次握手释放连接?

(1)某个应用进程首先调用 close 主动关闭连接,这时 TCP 发送一个 FIN M;
(2)另一端接收到 FIN M 之后,执行被动关闭,对这个 FIN 进行确认。它的接收也作为文件结束符传递给应用进程,因为 FIN 的接收意味着应用进程在相应的连接上再也接收不到额外数据;
(3)一段时间之后,接收到文件结束符的应用进程调用 close 关闭它的 socket。这导致它的 TCP 也发送一个 FIN N;
(4)接收到这个 FIN 的源发送端 TCP 对它进行确认。

参考

https://blog.****.net/weixin_44936889/article/details/104606259