python 和数据结构

https://www.nowcoder.com/discuss/231656?type=post&order=time&pos=&page=1

 1  python为什么会慢?

 是一个动态的解释型语言,python 中的值不少存储在缓存区而是分散存储在对象中

python 是一门解释器语言,C++ 编译语言,也就是说C++ 程序首先要编译源程序,生成可执行文件一个class 文件,而python 写完程序,提交到解释器,解释器会立刻将第一行代码翻译成机器码,然后将这行代码交给CPU 去执行,然后进行下一行,翻译第二行代码,再交给CPU 去执行,所以python 要比那些编译型语言执行起来要慢。

之前对java 的判断有些问题,java 是解析语言,全是封好的包。

2 什么是内存泄漏? 什么时候会内存泄漏?

 动态申请内存空间没有被正常释放,但也不能继续被使用的情况,没有释放内存。

3 指针和引用? 什么时候用指针?什么时候引用?

指针可以不初始化,引用必须初始化,且绑定后不能再变,向函数中传递指针和传递指针的引用的区别。

传递指针: 会先复制该指针,在函数内部使用的是复制后的指针,这个指针与原来的指针指向相同的地址,如果在函数内部将复制后的指针指向了另外的新的对象,那么不会影响原有的指针。

传递指针引用:如果将传递进来的指针指向了新的对象,那么原始的指针也就指向了新的对象,这样就会造成内存泄漏,因为原来指针指向的地方已经不能再引用了。 即使没有将传递进来的指针指向新的对象,而是在函数结束的时候释放了指针,那么在函数外部就不能再使用原有的指针了 ,因为原来的内存已经被释放了。

4 数据结构有哪些?

 堆 数组 列表 栈

 5 什么是堆?

平时只用数组模拟堆,不知道真实的结构,认为是父节点-子节点这样状态的数据结构(超高频率问题,一般由程序员释放,若程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收,分配方式类似于链表,向上增长,栈的分割开辟在程序运行时运行,内核顺着链表找到一块足够大的空间交给程序,如果没找到就构调无用内存再找一次。)

6 堆和栈的区别

栈就是存东西的空间,往最里面存,出来是最外面出来(超高频问题,函数运行时分配,函数结束时释放,由编译器自动分配释放,存放为运行函数而分配的局部变量,函数参数,返回数据,返回地址等。)向下开辟,速度很快,局部性能很好的话会和寄存器交互,存PC指针,函数参数多也会组成帧存到栈里面。

10 进程和线程

(超高频问题,我看了深入理解计算机系统后的总结:1 进程就是活着的程序,程序时一些文本,运行着程序就是程序,是系统进行资源调度和分配的基本单位,掌握资源,包括内存等,线程就是轻量级进程,是CPU 调度和分派基本单位。2 由于进程占有资源,压栈和出栈慢,所以切换不灵活,线程不占资源,只占必要的资源(递归要压栈所以要一点资源),所以线程容易通信-》在进程分来的内存中直接通信,容易并发-> 切换灵活。同一进程的线程切换速度很快,因此线程开销小,地址空间,进程独立,同一进程的线程共享资源,对其他进程的线程独立。

11 ID3 ,C4.5 等基本数,是二叉树还是多叉树,被切过的特征还会再切吗?

离散特征(离散数量>2)是多叉分类,连续是二叉分裂,连续可以再切,离散不可以(先做集合,遍历特征,保存最大的信息增益位置,然后对特征切分,切分后把这个特征从集合中删掉,所以离散特征完就不在切了。

12 介绍BN 。 预白化,训练快,sigmoid 两端饱和梯度小,BN 可以缩放到线性区, 2 分布学习,NN深了之后每一层分布都会偏移,BN 压缩分布使得分布趋近于一致。 3 BN 可以看做一定程度的数据扩充,数据做了抖动处理,注意BN 的训练过程要记得,当前批次归一化,预测的时候是全部数据,而且BN 层有两个超参数要优化。

13  GBDT 和RF 哪个树比较深?

RF 深,说了boost 和bagging 的思想,boost 使用低方差学习器去拟合偏差,所以XGB 和 LGB 有树 深的参数设置,RF 是拟合方差,对样本切对特征切,构造多样性样本集合,每棵树甚至不剪枝。

14 XGB 特征重要性程度是怎么判断的?

14.1 gain 增益意味着相应的特征对通过对模型中的每个树采取每个特征的贡献而计算出的模型的相对贡献,与其他特征相比,此度量值得较高值意味着它对生成预测更为重要。

14.2 cover 覆盖度 量是指与此功能相关的观测的相对数量,例如如果您有100个观察值,4个特征和3棵树,并且假设特征1分别用于决策树1,树2和树3中10个,5个和2个观察值的叶结点,那么该度量将计算机功能的覆盖范围为10+5+2=17 个观测值,这将针对所以决策树结点进行计算,并将17个结点占总的百分比表示所有功能的覆盖指标。

14.3 freq 频率(频率)是表示特定特征在模型树种发生的相对次数的百分比,在上面的例子中,如果feature1 发生在2个分裂中,1个分裂和3个分裂在每个树1,树2和树3中,那么特征1的权重将是2 1 3 =6 ,特征1 的频率被计算为其在所有特征的权重上的百分比权重。

15 XGB 很容易理解它的回归和二分类,如何理解多分类呢?

用onehot +softmax ,但是每一棵树如何是拟合softmax 前一步呢:构造300颗树,拟合三分类,再softmax 。(onehot 后,输入标签是一个向量,对向量中每一个预测点集成一群树)

16 XGB 和LGB 区别

特征排序,特征切分和直方图和全排序

1)更快的训练速度和更高的效率,LGB 使用基于直方图的算法

2) 直方图做差加速,一个子节点的直方图可以通过父节点的直方图减去兄弟节点的直方图得到,从而加速计算。

3) 更低的内存占用: 使用离散的箱子(bin)保存并替换连续值导致更少的内存占用。

4) 更高的准确率(相比于其他任何提升算法): 它通过leaf-wise 分裂方法(在当前所有叶子节点中选择分裂收益最大的节点进行分裂,如此递归进行)很明显leaf-wise 这种做法很容易过拟合,因为容易陷入比较高的深度中,因此需要对最大深度做限制,从而避免过拟合。产生比level -wise 分裂方法,(对每一层所有节点做无差别分裂,可能有些节点的增益非常小),对结果影响不大,但是xgboost 也进行了分裂,带来了更复杂的数,这就是实现更高准确率的主要因素。

5) 大数据处理能力:相比于xgboost ,由于它们在训练时间上的缩减,它同样能够具有处理大数据的能力。

6) 支持并行学习

7) 局部采样: 对梯度大的样本(误差大)保留,对梯度小的样本进行采样,从而使得样本数量降低,提高运算速度。

17 BN,Dropout 

在前向传播时,让某个神经元的激活值以一定的概率p 停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征。

其实就是个Bagging策略,构造子网组合。

18 腾讯比赛特征如何离散化啊? 连续性特征也能交叉啊为什么不交叉?

离散化就是数据分桶,按百分位分桶,百分位分桶比较均匀,百分位是数据排序的百分位,而不是区间的百分位。

连续性特征交叉: 连续性特征映射成离散特征后,可以和连续性特征一起送到嵌入层里。

19 重载和重写

重写是对虚函数的重写。所谓重载就是同名函数参数表不同,编译时会对函数改名,其实运行的时候他们已经不是同名了。重写是虚函数重写,子类对父类的非虚函数在写一遍叫重定义或者隐藏,反正不是重写,重写是对虚函数的重写。

20 大数据 买东西 找买东西最多的100个,怎么做?

建个哈希表,小顶堆

21 MAP 底层怎么做的?

log(n) 恍然大悟索引是二叉树。

22 L1 ,L2 不同?L1 为什么能稀疏?

从数学分布讲了,一个是拉普拉斯分布,一个是高斯分布,讲了图解为什么L1 能稀疏,一个圈一个菱形,容易交在轴上。工程上将了,L1的近似求导,区间内0 区间外优化,然后L2 是直接求导比较简单。

22 哪些学习器是凸优化的?

LR sigmoid logloss 凸优,线性回归,最小二乘凸优,SVM 凸优。NN 肯定不凸优,因为往往收敛到鞍点,PCA 无数学解,但是利用特征值去做反而得到最优解。

23 特征重要性你怎么做,例如特征组合和删除,调参你是怎么调的?

特征组合用onehot ,交叉,embeding。组合的话你要看实际分布,讲了自己构造过的一个和标签有线性关系的组合,说自己用的是遍历的方法,用两两数学关系构造新特征,看和标签的线性关系。

调参:

第一祖传参数: 比如树模型的深度,采样频率等,这个主要还是经验

第二部调参:比如尝试新特征,特征采样频率要设置为1.

7 激活函数 leakRELU 

leakrelu 函数是relu 激活函数的改进版本,解决部分输入会落入硬饱和区,导致对应的权重无法更新的问题。

f(x)=max(x,leak*x)

左边缩小方差,右边保持方差,方差整体还是缩小的,而均值得不到保证。

8 鞍点是什么?

不是局部最优点,鞍点在一个方向上升,所以很容易坐滑滑梯从上方滑到鞍点,另一个方向是下降,所以可以坐着下降的滑滑梯下去,但是鞍点这里梯度是0,是平的,所以优化就容易困在这里,前面多走几步就是滑滑梯但是他无路可走。

9 用过GRU吗? 为什么LSTM 能够记忆长时记忆。

GRU 用过一次,在哪用的,用的记忆们,保证长时记忆传输。

10 为什么用CNN? 然后面试官介绍推荐领域内的另一个东西(embeding) ,这个embeding 映射了隐向量,你觉得是CNN 交叉好呢? 还是隐向量好呢?

Embeding ,回答是偏向于场景,编码领域内的一个特点: 只有局部相关,时不变,所以用CNN ,做全局相关的Embeding 反而不好,推荐里面特征离散化后稀疏,而且特征间本省可能具有高阶交互信息,所以映射成隐向量效果会较好,如果是推荐,我建议用隐向量而不是CNN,这其实是由场景决定的,是数据的特点决定选用什么学习器,使用什么网络。

11 静态内存和动态内存?

讲了static 和堆栈是静态,编译的时候决定了大小,动态内存可以自由开辟堆。

12 堆是?

说了向上开辟,速度慢,运行时改,然后开辟的过程,链表存着下一个位置和这一块有没有使用,如果没找到就析构合并内存再找,再找不到返回null。

13 堆栈是?

说了向下开辟,速度快,编译时分配,主要是存PC 指针,然后函数入口参数多组成栈帧存进去等着恢复。

14  malloc 和new 区别 free 和delete?

14.1 一个是函数,一个是关键字

14.2 malloc 要算大小,返回void* ,强转后转完后的类型用,要自己算大小,new 的时候传类型,就比如100个int,然后直接开100个就好了,他自动将int 长度算进去。

14.3 malloc 再堆上,new 在自由存储去,

自由存储区是C++ 中通过new 与delete 动态分配和释放对象的抽象概率,而 堆heap 是C 语言和操作系统的术语,是操作系统维护的一块动态分配内存。

new 所申请的 内存区域在C++ 中称为自由存储区,籍由堆实现的自由存储,可以说new 所申请的内存区域在堆上。

堆与自由存储区还是有区别的,它们并非等价。

15 python 怎么解决循环引用的?

python 本身解不了循环引用的问题,循环引用要靠自己析构,对python 来说,循环引用的东西就算程序关了都还在,但python 有个库函数可以发现循环引用位置,然后调用垃圾收集器析构掉就好。

16 计网了解不? 计算机网络TCP 和UDP 的区别?

UDP 主要用于那些对高速传输和实效性有较高要求的通信或广播通信。

TCP 用于在传输层有必要实现可靠性传输的情况。

16.1 TCP 面向连接(如打电话要先拨号建立连接); UDP 是无连接的,即发送数据之前不需要建立连接。

16.2 TCP 提供可靠的服务,也就是说通过TCP 连接送达的数据,无差错,不丢失,不重复,且按序达到,UODP 尽最大努力交付,即不保证可靠交付。

16.3 TCP 面向字节流,实际上是TCP 把数据看成一连串无结构的字节流,UDP 是面向报文的; UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低

16.4 每一条TCP 连接只能是点到点的,UDP 支持一对一,一对多,多对一和多对多的交互通信。

16.5 TCP 首部开销20字节,UDP 的首部开销小,只有8个字节。

16.6 TCP 的逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道。

17 一个队列,想知道最大值,怎么做?

保存最大值和索引,出队就重新找,这一步是O(n), 然后入队更新值和索引。

18 如何优化?

这里给出了滑动窗口最大值的最优解法,我通常都是用5 的方法做滑动窗口最大值,实际上可以用双端队列。

deque 解法:

队列为空插入新数据,队列存的是索引,索引比大小的意思是索引对应的值比大小

非空,判断队首index 和当前窗口的关系,若是划过了,弹出。

循环判断新数据和队尾数据大小,队尾元素小于新的数据,就把队尾移除直到第一个比新数据大的,新数据插入。

每次更新窗口的时候,队首元素一定最大,

队列存的是index ,值是nums[index]

19 二维平面一些点,问距离某一个新点最近的是哪一个点?

暴力,复杂度O(N) 。KNN 学习器用的是kd 。

kd 树是平衡二叉树,用的思想的是二分查找,对所有数排序,如果在中间左边,就在左边找,否则在右边找,主要用kd 把平面划分成很多区域。

构建方法:

根结点-> 代表k 维度空间内所有实力点的矩形区域

对k 维递归切分,生成子节点。平面区域选择一个坐标轴和此坐标轴上的切分点,确定超平面,切分点垂直与选定坐标轴,划分区域为左右子区域。实例被分到两个区域,知道没有实例终止,实例保存在结点上。

最近邻查询:二叉搜索到叶节点,在回溯。

20 二维平面的一些点,每个点有一个数字,找每个字对用的凸包。

不会,讲了讲聚类的一些算法,主要是小波聚类找到边界点,在想办法最外边连起来。

难点在于不同数字可能相互混叠,要求是密度最大的算做一个数字,比如很多1,部分2,他们围成的凸包应该是1对应的凸包。

21 介绍CNN ,卷积层如何实现非线性

使用激活层。不然卷积都是在线性变换,CNN 的时不变性真的很适合用于信号处理,讲了时不变和局部权值共享,说CNN 是DNN 的特例。

卷积:对图像(不同的数据窗口数据) 和滤波矩阵(一组固定的权重) 做内积操作

卷积的重要的物理意义是: 一个函数(如: 单位响应) 在另一个函数(如: 输入信号) 上的加权叠加

卷积神经网络CNN 是多层感知机(MLP) 的变种,20世纪60年代,Hubel 等在研究猫脑皮层时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了CNN。

CNN: 局部连接和共享权重的方式,减少了的权值的数量使得网络易于优化,另一方面降低了过拟合的风险,该优点在网络的输入是多维图像时表现的更为明显,使图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建过程。在二维图像处理上有众多优势。

CNN 具有一些传统技术所没有的优点: 良好的容错能力,并行处理能力和自学习能力,可处理环境信息复杂,背景知识不清楚,推理规则不明确情况下的问题,允许样品有较大的缺损,畸变,运行速度快,自适应性能好,具有较高的分辨率,它是通过结果重组和减少权值将特征抽取功能融合进多层感知器,省略识别前复杂的图像特征抽取过程。

CNN 的泛化能力要显著优于其他方法,卷积神经网络已被应用于模式分类,物体检测和物体死别等方面,利用卷积神经网络模式分类器,将卷积神经网络作为通用的模式分类器,直接用于灰度图像。

22 假设我是一个不会优化算法的人,给我讲讲模拟退火?

优化的目的是为了满足机器学习可行的第二个条件,就比如我要是登山,优化算法的目的就是找到最高峰的位置,优化算法就是如何往上走的方法,传统的梯度下降就是盯着脚下路走,每一步都沿着向山顶的方向,每走到一个山顶时,四面都是下坡路,就站在山顶不动了,而模拟退火就是一个喝醉的人去登山,他每一步都知道往哪走是向上的方向,但是他喝醉了,可能会往上走也可能乱走。随着时间的流失,他喝的程度减轻了,就是醒酒了,乱走的可能性降低,然后完全醒酒了,就直接朝着向上的方向走了。

23 为什么能够跳出局部最优解? 为什么能走到最优解?

之所以梯度下降法不能跳出局部最优解,是因为梯度下降法只盯着向上的方向走,假如登山者站在了凳子上,那么他往哪个方向跳下凳子后,落脚点都是一个朝着凳子位置下落的方向,而梯度下降法只会朝着高处走,所以不会有跳下凳子这一步,模拟退火来自物理学的概念,表明自己学过热力学,然后讲了熵和分子运动,就算是走到凳子上,模拟退火在这里有一定概率跳下去凳子,因为他有概率朝着向下的方向走,只要他跳出了这个局部最优解,他就能朝着远处的山峰走去,另一方面模拟退火不一定能走到最优解的原因是加入局部最优解覆盖的范围较广,优于模拟退火走不了太远,可能跳着就回来了,

24  从ID3 讲到C4.5 讲到CART 讲到XGB 讲到LGB,boost 的从头到尾,RF 详细说了,还讲了lgb 的特征采样参数的坑,如何按叶分类。面试官补充为什么学习率和树深度的关系? 我感觉是树越深越小。

25 视频二分类,不平衡,算精准率,召回率,准确率。

召回率太重要了,因为这种我们可以虚警但是不能漏警,所以精确率不高可以接受。

如何提高精准率?

调分类阈值+大,但是召回率降低就回退。

正样本权重变高训练,用focalloss

Focalloss ?

何凯明用于检测任务的,为了解决one-stage 目标检测中正负样本比例严重失衡的问题,该损失函数降低了 大量简单负样本在训练中所占的权重,也可理解为一种困难样本挖掘。

作者认为one-stage 和two-stage 的表现差异主要原因是大量前景背景类别不平衡的问题,作者设计了一个简单密集型网络ReinaNet 来训练在保证速度的同时达到了精度最优。在双阶段算法中,在候选框阶段,通过得分和nms 筛选过滤掉了大量的负样本,然后在分类回归阶段又固定了正负样本比例,或者通过OHEM 在线困难挖掘使得前景和背景相对平衡,而one-stage 阶段需要产生约100k 的候选位置,虽然有类似的采样,但是训练仍然被大量负样本所主导。

 

 

 

你可能感兴趣的:(数据结构与算法)