科大讯飞笔试

一 选择题

1 线程和进程。

进程是i资源分配的最小单位,线程是CPU调度的最小单位。

一、线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。

二、进程为应用程序运行实例,是应用程序的一次动态执行,进程是由进程控制块、程序段、数据段3部分组成,一个进程可以包含若干线程,使用线程可以实现应用程序同时做几件事并且互相不干扰,进程是操作系统进程资源分配的单位。

三、线程适用范围

1、服务器中的文件管理或通信控制

2、前后台处理

3、异步处理

2 无向图的DFS。

3 线程的栈不可以共享

线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器

线程间共享的有:堆,全局变量,静态变量;

进程占有的资源有:地址空间,全局变量,打开的文件,子进程,信号量、账户信息。

线程共享的内容包括:

进程 代码段
进程 数据段
进程打开的文件描述符、
信号的处理器、
进程的当前目录和
进程用户 ID 与进程组 ID     

  线程独有的内容包括:

线程 ID
寄存器组的值
线程的堆栈
错误返回码
线程的信号屏蔽码 

4 链接器生成的是啥文件。

链接器(Linker)是一个程序,将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件。目标文件是包括机器码和链接器可用信息的程序模块。简单的讲,链接器的工作就是解析未定义的符号引用,将目标文件中的占位符替换为符号的地址。

5 下列和神经网络的dropout效果类似的是

A Bagging

B boosting

c stacking

A. dropout可以看作是多个模型的平均

6 CPU加速比

在 CPU 系统设计中,欲对 ALU 进行加速。经分析,已知 ALU 原运行时间占 40% 。并将 ALU 的速度提高到原来的 10 倍。则改进前后 CPU 的加速比是( )。

1.56。令CPU原运行时间为T,则ALU 原运行时间占 40%T,提速后变为40/10% = 4%T。加速比为:T/(60%T + 4%T) =1.56。

7

下面代码在64位Linux系统编译执行,输出结果是____。

#include <stdint.h> 

#include <stdio.h> 

void print_size(int32_t array[10]){ 

 printf("%d\n", sizeof(array)); 

} 

int main () { 

 int32_t myArray[10]; 

 printf("%d ", sizeof(myArray)); 

 print_size(myArray); 

} 

本题要注意几点:

1、sizeof(数组名),返回的整个数组占据的字节数。在这里,数组长度为10,每个4字节,所以,总共40字节。

2、在64位操作系统中,地址为64位,也就是指针64位,占8字节。

2、通过函数调用后,数组名退化成指针,占8字节。

注意传递的时候就变成了指针。

8 纯虚函数

带有纯虚函数的类是抽象类。抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。抽象类声明了一组派生类共同操作接口的通用语义,而接口的完整实现,即纯虚函数的函数体,要由派生类自己给出。但抽象类的派生类并非一定要给出纯虚函数的实现,如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类。
纯虚函数是一种特殊的虚函数,它的一般格式如下(C++格式):
class <类名>
{
virtual <类型><函数名>(<参数表>)=0;

};

9 socket

套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。可以将套接字看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信 [3] 。
Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。 Socket是由IP地址和端口结合的,提供向应用层进程传送数据包的机制 [2] 。套接字Socket=(IP地址:端口号),套接字的表示方法是点分十进制的lP地址后面写上端口号,中间用冒号或逗号隔开。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。例如:如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)

10 IPV6

IPV6与IPV4相比,地址增大到1bit,为便于阅读和操纵这些地址,IPV6使用2计法。
正确答案:
1 128
2 冒号十六进制

1.ipv6相对于IPv4的地址空间从32位扩展为提高到128位

2.ipv6实现了包头设计的简化,降低了网络设备多包处理的负荷

3.ipv6实现了地址的自动化配置,无需部署DHCP也能部署

为了实现ipv6的地址解析、路由、网络控制消息传递等功能,网络需要配合实现邻居发现协议、ICMPV6、DHCPv6、OSPFv3、BGP4+等协议部署

11 神经网络的激活函数

激活函数起到去线性化作用,所以常用一些分段函数,平滑曲线等,如果不用激活函数(其实相当于激活函数是f(x) = x),在这种情况下你每一层节点的输入都是上层输出的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,所以引进了激活函数。
常用的激活函数主要有:
(1)sigmoid函数

(2)tanh函数

(3)ReLU函数

(3)Leaky ReLU函数

(1)非线性:即导数不是常数。这个条件是多层神经网络的基础,保证多层网络不退化成单层线性网络。这也是激活函数的意义所在。下面看一下激活函数使用线性函数时会发生什么

由上可见,任意多个线性函数的组合还是线性函数,因此只要隐藏层的输出是线性的,无论多少层,都是和一个隐藏层是一回事,只有在线性回归问题中的输出层才会用到线性激励函数,但是实际上对于回归任务,你完全可以不使用激活函数。

(2)几乎处处可微:可微性保证了在优化中梯度的可计算性。传统的激活函数如sigmoid等满足处处可微。对于分段线性函数比如ReLU,只满足几乎处处可微(即仅在有限个点处不可微)。对于SGD算法来说,由于几乎不可能收敛到梯度接近零的位置,有限的不可微点对于优化结果不会有很大影响。

(3)计算简单:激活函数在神经网络前向的计算次数与神经元的个数成正比,因此简单的非线性函数自然更适合用作激活函数。

(4)非饱和性(saturation):饱和指的是在某些区间梯度接近于零(即梯度消失),使得参数无法继续更新的问题。最经典的例子是Sigmoid,它的导数在x为比较大的正值和比较小的负值时都会接近于0。更极端的例子是阶跃函数,由于它在几乎所有位置的梯度都为0,因此处处饱和,无法作为激活函数。ReLU在x>0时导数恒为1,因此对于再大的正值也不会饱和。但同时对于x<0,其梯度恒为0,这时候它也会出现饱和的现象(在这种情况下通常称为dying ReLU)。Leaky ReLU和PReLU的提出正是为了解决这一问题。

(5)单调性(monotonic):即导数符号不变。这个性质大部分激活函数都有,除了诸如sin、cos等。个人理解,单调性使得在激活函数处的梯度方向不会经常改变,从而让训练更容易收敛。

(6)输出范围有限:有限的输出范围使得网络对于一些比较大的输入也会比较稳定,这也是为什么早期的激活函数都以此类函数为主,如Sigmoid、TanH。但这导致了前面提到的梯度消失问题,而且强行让每一层的输出限制到固定范围会限制其表达能力。因此现在这类函数仅用于某些需要特定输出范围的场合,比如概率输出(此时loss函数中的log操作能够抵消其梯度消失的影响)、LSTM里的gate函数。

(7)接近恒等变换(identity):即约等于x。这样的好处是使得输出的幅值不会随着深度的增加而发生显著的增加,从而使网络更为稳定,同时梯度也能够更容易地回传。这个与非线性是有点矛盾的,因此激活函数基本只是部分满足这个条件,比如TanH只在原点附近有线性区(在原点为0且在原点的导数为1),而ReLU只在x>0时为线性。这个性质也让初始化参数范围的推导更为简单。额外提一句,这种恒等变换的性质也被其他一些网络结构设计所借鉴,比如CNN中的ResNet和RNN中的LSTM。

(8)参数少:大部分激活函数都是没有参数的。像PReLU带单个参数会略微增加网络的大小。还有一个例外是Maxout,尽管本身没有参数,但在同样输出通道数下k路Maxout需要的输入通道数是其它函数的k倍,这意味着神经元数目也需要变为k倍;但如果不考虑维持输出通道数的情况下,该激活函数又能将参数个数减少为原来的k倍。

(9)归一化(normalization):这个是最近才出来的概念,对应的激活函数是SELU,主要思想是使样本分布自动归一化到零均值、单位方差的分布,从而稳定训练。在这之前,这种归一化的思想也被用于网络结构的设计,比如Batch Normalization。

(10)zero-centered:Sigmoid函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。举例来讲,对σ(∑wixi+b),如果所有xi均为正数或负数,那么其对wiwi的导数总是正数或负数,这会导致如下图红色箭头所示的阶梯式更新,这显然并非一个好的优化路径。深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。

12 本地用户通过键盘登录系统时,首先获得键盘输入信息的程序是______。

A.命令解释程序
B.中断处理程序
C.系统调用程序
D.用户登录程序

、[解析]
当用户按键时,键盘接口会得到一个代表该按键的键盘扫描码,同时产生一个中断请求。键盘中断服务程序先从键盘接口取得按键的扫描码,然后根据其扫描码判断用户所按的键并作相应的处理,最后通知中断控制器本次中断结束并实现中断返回。
因此,本地用户通过键盘登录系统时,首先获得键盘输入信息的程序是中断处理程序。

13 银行家算法

链接:https://www.nowcoder.com/questionTerminal/9b8af07960074945879a5522248d96e0
来源:牛客网

银行家算法中,若出现以下资源分配情况:

资源

进程

最大需求量

R1 R2 R3

已分配资源量

R1 R2 R3

剩余资源量

R1 R2 R3

P0

P1

P2

P3

P4

7 5 3

3 2 2

9 0 2

2 2 2

4 3 3

0 1 0

2 0 0

3 0 2

2 1 1

0 0 2

3 3 2

试问:( 1 )该系统状态是安全的吗?请说明原因。

( 2 )如果进程依次有如下资源请求,系统将怎样进行资源分配?

P1 :( 1 , 0 , 2 )

P4 :( 3 , 3 , 0 )

P0 :( 0 , 2 , 0 )

答:( 1 ) P1 的请求( 3 , 2 , 2 )是系统剩余资源( 3 , 3 , 2 )能满足的,故 P1 能运行完, P1 释放资源,使得 P2 的申请能得到满足, … ,进程按 P1 , P3 , P0 , P2 , P4 顺序执行,每个进程都可以获得需要的资源运行完毕,故当前状态是安全的。

( 2 ) P1 请求( 1 , 0 , 2 ):剩余资源:( 2 , 3 , 0 ),假设分配后:

进程 需求量 已获得资源数 尚需资源数

P0 7 , 5 , 3 0 , 1 , 0 7 , 4 , 3

P1 3 , 2 , 2 3 , 0 , 2 0 , 2 , 0

P2 9 , 0 , 2 3 , 0 , 2 6 , 0 , 0

P3 2 , 2 , 2 2 , 1 , 1 0 , 1 , 1

P4 4 , 3 , 3 0 , 0 , 2 4 , 3 , 1

系统按 P1 , P3 , P0 , P2 , P4 顺序执行,每个进程均能执行完。 P1 的需求可以满足。

P4 请求( 3 , 3 , 0 ):剩余资源:( 2 , 3 , 0 )。

进程 需求量 已获得资源数 尚需资源数

P0 7 , 5 , 3 0 , 1 , 0 7 , 4 , 3

P1 3 , 2 , 2 3 , 0 , 2 0 , 2 , 0

P2 9 , 0 , 2 3 , 0 , 2 6 , 0 , 0

P3 2 , 2 , 2 2 , 1 , 1 0 , 1 , 1

P4 4 , 3 , 3 0 , 0 , 2 4 , 3 , 1

系统剩余资源不能满足 P4 的要求,不能分配。

P0 请求( 0 , 2 , 0 ):剩余资源:( 2 , 3 , 0 )。

进程 需求量 已获得资源数 尚需资源数

P0 7 , 5 , 3 2 , 4 , 0 7 , 2 , 3

P1 3 , 2 , 2 3 , 0 , 2 0 , 2 , 0

P2 9 , 0 , 2 3 , 0 , 2 6 , 0 , 0

P3 2 , 2 , 2 2 , 1 , 1 0 , 1 , 1

P4 4 , 3 , 3 0 , 0 , 2 4 , 3 , 1

假设分配后,还剩余系统资源: ( 2 , 1 , 0 ) P0~P4 尚需的资源数均不能得到满足,不能对 P0 分配。

14 银行家算法是一种( )算法。

死锁避免
死锁预防
死锁解除
死锁检测

选A。银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。

15 GPU加速

OPENCL
OPENGL
vulkan
CUDA

16 动态库符号隐藏

https://blog.csdn.net/mrpre/article/details/84638594?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.compare

https://blog.csdn.net/weixin_43939128/article/details/104603614?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1&spm=1001.2101.3001.4242

17 MLE和MAP

不带惩罚项的交叉熵是MLE
带的是MAP

二 编程题

1 最小二乘

#include <iostream>
#include <numeric>
using namespace std;

int main(int argc, char const *argv[])
{
    int x[]={1,2,3,4},y[]={6,5,7,10};
    double a,b;
    int xy=0,x2=0;
    double sx=0,sy=0;
    for (int i = 0; i < 4; ++i)
    {
        xy+=x[i]*y[i];
        x2+=x[i]*x[i];
        sx+=x[i];
        sy+=y[i];
    }
    a=(4*xy-sx*sy)/(4*x2-(sx)*(sx));
    b=sy/4-a*sx/4;
    cout << a<<endl<<b;


    return 0;
}

2 如果A和B拼接为AB,而且A反过来和B一样,则AB为对称字符串,求输入字符串的最大对称子串。

例如输入:121
则为2,因为根据题意AB必须为偶数长度,所以返回的是2。

/*
* @Author: lenovouser
* @Date:   2020-07-31 14:49:38
* @Last Modified by:   lenovouser

* @Last Modified time: 2020-07-31 14:50:41

*/

#include <iostream>
#include <string>
using namespace std;

int f(string::iterator s,string::iterator e)
{
    if (s<=e)
    {
        if (*s!=*e)
        {
            return min(f(s+1,e),f(s,e-1))+1;

        }
        else
        {

            return f(s+1,e-1);
        }
    }
    else
    {
        return 0;
    }

}
int main(int argc, char const *argv[])
{
    string s;
    cin>>s;
    int r=s.size()-f(s.begin(),s.end()-1);
    if(r%2)
    {
        cout<<r-1;
    }
    else
    {
        cout<<r;
    }
    return 0;
}

用的是递归,最好复杂度为O(n/2)。最坏的复杂度是个二叉树,叶子节点为12233445566…n。除了两个端点是一个,中间都是2个,这是个几何级数,最后也就是O(2n-2)同级。

3 假如现在有数组,只能相邻位置交换或者首尾交换,求颠倒数组所需的最少交换次数。

例如输入5,输出4
输入3,输出1
输入4,输出2
这个容易进入1+(n-2)(n-3)/2的误区。
举个例子:1234567
首尾一次7234561
然后
7234651
7236451
7263451
7623451
7623541
7625341
7652341
7652431
7654231
7654321
只往左移。这样是11次。
然而:
7234516
6234517
2634517
2635417
2653417
2654317
7654312
7654321
才9次。不只有左边才可以移的。
参考https://blog.csdn.net/qq_41890797/article/details/81109984
这还是ACM的一道题。
https://blog.csdn.net/Angeliaaa/article/details/81105510
但感觉说不清楚为啥分成n/2和n-n/2就是最小。
m
(m-1)/2+n*(n-1)/2=(mm+nn-(m+n))/2
假如m+n为常数,那么为了使mm+nn最小确实应该使得m和n尽量接近。
但注意点看的话其实还有区别,因为,圆桌会议只需要顺序相反,位置不需要相反,不需要原来最大的位置放最小。
像1-7的环,分的直线需要满足两端和为8,那么就是6712和345两条直线。
如果是偶数,比如123456 那么找不到满足的3-3直线分法,这样的直线两端和不可能为7 。但是如果是1-8,那么就可以4-4分,7812,3456。
所以先判断如果奇数长度,那么就可以用上述方法。如果偶数为2的倍数,那么6需要分为4-2,也就是n/2+1和n/2-1。如果是4的倍数,就分为两个n/2。

14 Segment fault

https://www.cnblogs.com/wahaha02/p/8034112.html
segment fault 常见触发源
内核会依据下列条件来判断是否发生了用户态段错误,并上报SIGSEGV信息给用户态task:

用户态数据段的地址越界
用户态代码段的指令读取异常
访问操作与所访问的内存页面权限不匹配
非对齐访问(一般是上报SIGBUS,但mips会上报SIGSEGV)
导致段错误的常见编程范式有:

使用未初始化变量
使用已释放的内存
数组越界
多进程下使用不可重入函数
内存被踩(如栈被踩导致pc或数据寻址错误等)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值