C++
1.sizeof,字节对齐问题。
struct mystruct1{
short a1;
short a2;
short a3;
};
struct mystruct2{
bool b1;
bool b2;
char c;
int i;
};
struct mystruct3{
bool b1;
bool b2;
};
struct mystruct4{
bool b1;
int i;
bool b2;
};
分析:在32位系统中測试sizeof(mystruct1)=6,sizeof(mystruct1)=8,sizeof(mystruct3)=2,sizeof(mystruct4)=12,sizeof(bool)=1。在32位系统下。bool占一个字节。结构体占的总字节数是该结构体中最大类型所占字节数的整数倍。
mystruct4中因为第一个bool和第二个bool不连续出现。因此各占4个字节。以下是32位系统和64位系统下,各数据类型所占的字节数
32位操作系统:
类型 | 占字节数 |
---|---|
char | 1个字节(固定) |
*(即指针变量) | 4个字节(32位机的寻址空间是4个字节) |
short int | 2个字节(固定) |
int | 4个字节(固定) |
unsigned int | 4个字节(固定) |
float | 4个字节(固定) |
double | 8个字节(固定) |
long | 4个字节(VS下验证是4个字节) |
unsigned long | 4个字节(变化,事实上就是寻址空间的地址长度数值。VS下验证是4个字节) |
long long | 8个字节(固定) |
64位操作系统:
类型 | 占字节数 |
---|---|
char | 1个字节(固定) |
*(即指针变量) | 8个字节 |
short int | 2个字节(固定) |
int | 4个字节(固定) |
unsigned int | 4个字节(固定) |
float | 4个字节(固定) |
double | 8个字节(固定) |
long | 8个字节 |
unsigned long | 8个字节(变化,事实上就是寻址控件的地址长度数值) |
long long | 8个字节(固定) |
除了*与long随操作系统子长变化而变化外,其它的都固定不变(32位和64相比)。
bool 1个字节 char 1个字节 int 4个字节 float 4个字节 double 8个字节 long long 8个字节。
2.(360)以下哪种c/C++分配内存的方法将分配的空间初始化为0
A.realloc B.malloc C.new D.calloc
答案: D,C语言跟内存申请相关的函数主要有 alloca、calloc、malloc、free、realloc等。alloca是向栈申请内存,因此无需释放;malloc分配的内存是位于堆中的。并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间;calloc则将初始化这部分的内存。设置为0;realloc则对malloc申请的内存进行大小的调整。堆由用户管理,即由用户释放内存,堆仅仅能动态分配,堆是不连续的。栈由操作系统管理,可动态也可静态分配,栈是连续的。
- 从静态存储区域分配.
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。比如全局变量、static变量。
- 在栈上创建
在运行函数时,函数内局部变量的存储单元都能够在栈上创建,函数运行结束时这些存储单元自己主动被释放。栈内存分配运算内置于处理器的指令集中。效率非常高,可是分配的内存容量有限。 - 从堆上分配,亦称动态内存分配.
程序在运行的时候用malloc或new申请随意多少的内存。程序猿自己负责在何时用free或delete释放内存。动态内存的生存期由用户决定,使用非常灵活。但问题也最多.
3.(奇虎360)以下哪个选项是错误的?
A.堆和栈都能够动态分配
B.堆和栈都能够静态分配
C.堆的大小仅受操作系统影响,栈的大小一般比較小
D.在堆上频繁new/deleteeasy产生内存碎片,栈没有这个问题
答案: B
- 栈(操作系统):由编译器自己主动分配释放 ,存放函数的參数值,局部变量的值等。其操作方式相似于数据结构中的栈,栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完成马上释放。在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的。在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),假设申请的空间超过栈的剩余空间时。将提示overflow。因此。能从栈获得的空间较小。
- 堆(操作系统): 一般由程序猿分配释放, 若程序猿不释放。程序结束时可能由OS回收。分配方式倒是相似于链表。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并非一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。堆是向高地址扩展的数据结构,是不连续的内存区域。
这是因为系统是用链表来存储的空暇内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。
由此可见。堆获得的空间比較灵活。也比較大。
- 全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的 全局变量和静态变量在一块区域。 未初始化的全局变量和未初始化的静态变量在相邻的另 一块区域。
程序结束后由系统释放。
- 文字常量区:常量字符串就是放在这里的。程序结束后由系统释放 。
- 程序代码区:存放函数体的二进制代码。
- 堆(数据结构):堆能够被看成是一棵树,如:堆排序。
- 栈(数据结构):一种后进先出的数据结构。
4.(奇虎360)
struct sttest{
int a;
bool b;
char d;
short c;
union
{
char e[200];
struct
{
long f;
int g[40];
}h;
}i;
int (*j)(int v,char *r);
};
64位系统下sizeof(sttest)是多大?
答案: int占4个字节。bool占1个字节。char占1个字节,short占2个字节。union中char型数据占具的空间最大,因此union占200个字节。函数指针占8个字节。整个结构体占字节数必须是最大类型(8字节)的整数倍,而int。bool。char和short合起来占8个字节。因此sizeof(sttest)=8+200+8=216个字节。
操作系统
1.(奇虎360)linux系统中,对file.sh运行#chmod 645 file.sh后,该文件的权限是什么?
答案::-rw-r—r-x。每一文件或文件夹的訪问权限都有三组,每组用三位表示,分别为文件属主的读、写和运行权限。与属主同组的用户的读、写和运行权限。系统中其它用户的读、写和运行权限。以下列文件为样例来说明该命令,假如运行命令ls -al之后得到:
-rw-r–r– 1 root root 296K 11-13 06:03 log2012.log
第一列共同拥有10个位置,第一个字符指定了文件类型。在通常意义上,一个文件夹也是一个文件。假设第一个字符是横线,表示是一个非文件夹的文件。假设是d,表示是一个文件夹。
从第二个字符開始到第十个共9个字符。3个字符一组,分别表示了3组用户对文件或者文件夹的权限。权限字符用横线代表空许可,r代表仅仅读,w代表写,x代表可运行。
数字与字符相应关系例如以下:
r=4,w=2,x=1
若要rwx属性则4+2+1=7
若要rw-属性则4+2=6;
若要r-x属性则4+1=7。
2.(奇虎360)for(i=0;i<4;i++){
fork();
printf(“-\n”);
}
打印多少个“-”
答案:
3.(唯品会)内存泄漏与内存溢出的差别。
答案:内存溢出 out of memory。是指程序在申请内存时。没有足够的内存空间供其使用,出现out of memory。比方申请了一个integer,但给它存了long才干存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害能够忽略,但内存泄露堆积后果非常严重。不管多少内存,迟早会被占光。
memory leak会终于会导致out of memory!
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete)。结果你申请到的那块内存你自己也不能再訪问(或许你把它的地址给弄丢了),而系统也不能再次将它分配给须要的程序。
一个盘子用尽各种方法仅仅能装4个果子,你装了5个,结果掉倒地上不能吃了。
这就是溢出!比方说栈,栈满时再做进栈必然产生空间溢出。叫上溢,栈空时再做退栈也产生空间溢出。称为下溢。
就是分配的内存不足以放下数据项序列,称为内存溢出.
以发生的方式来分类,内存泄漏能够分为4类:
(1).常发性内存泄漏。
发生内存泄漏的代码会被多次运行到。每次被运行的时候都会导致一块内存泄漏。
(2).偶发性内存泄漏。发生内存泄漏的代码仅仅有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的或许就变成了常发性的。所以測试环境和測试方法对检測内存泄漏至关重要。
(3).一次性内存泄漏。发生内存泄漏的代码仅仅会被运行一次,或者因为算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比方,在类的构造函数中分配内存。在析构函数中却没有释放该内存。所以内存泄漏仅仅会发生一次。
(4).隐式内存泄漏。程序在运行过程中不停的分配内存,可是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏。因为终于程序释放了全部申请的内存。可是对于一个server程序,须要运行几天。几周甚至几个月,不及时释放内存也可能导致终于耗尽系统的全部内存。所以,我们称这类内存泄漏为隐式内存泄漏。
4.(唯品会)cache设计的目的是什么?
答案:对大量典型程序运行情况的分析结果表明,在一个较短的时间间隔内。由程序产生的地址往往集中在存储器逻辑地址空间的非常小范围内。指令地址的分布本来就是连续的,再加上循环程序段和子程序段要反复运行多次。因此,对这些地址的訪问就自然地具有时间上集中分布的倾向。
数据分布的这样的集中倾向不如指令明显,但对数组的存储和訪问以及工作单元的选择都能够使存储器地址相对集中。这样的对局部范围的存储器地址频繁訪问,而对此范围以外的地址则訪问甚少的现象。就称为程序訪问的局部性。
依据程序的局部性原理。能够在主存和CPU通用寄存器之间设置一个快速的容量相对较小的存储器。把正在运行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用。这对提高程序的运行速度有非常大的作用。这个介于主存和CPU之间的快速小容量存储器称作快速缓冲存储器(Cache)。
系统正是依据此原理,不断地将与当前指令集相关联的一个不太大的后继指令集从内存读到Cache,然后再与CPU快速传送,从而达到速度匹配。
CPU对存储器进行数据请求时。通常先訪问Cache。因为局部性原理不能保证所请求的数据百分之百地在Cache中。这里便存在一个命中率。
即CPU在任一时刻从Cache中可靠获取数据的几率。
命中率越高,正确获取数据的可靠性就越大。一般来说,Cache的存储容量比主存的容量小得多。但不能太小,太小会使命中率太低;也没有必要过大,过大不仅会添加成本,并且当容量超过一定值后,命中率随容量的添加将不会有明显地增长。
内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU。操作系统会依据哪些数据属于LRU而将其移出内存而腾出空间来载入另外的数据。
什么是LRU算法? LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的。
为了尽量降低与理想算法的差距,产生了各种精妙的算法。最少使用页面置换算法便是当中一个。
LRU算法的提出。是基于这样一个事实:在前面几条指令中使用频繁的页面非常可能在后面的几条指令中频繁使用。反过来说,已经非常久没有使用的页面非常可能在未来较长的一段时间内不会被用到。这个,就是著名的局部性原理——比内存速度还要快的cache,也是基于相同的原理运行的。
因此。我们仅仅须要在每次调换时,找到最少使用的那个页面调出内存。这就是LRU算法的全部内容。
编译原理
1.2.(奇虎360)代码生成阶段的主要任务是
答案:把中间代码变换成依赖详细机器的目标代母
机器学习
1.(奇虎360)下列对l1范数正则化描写叙述不对的是
A.相当于MAP预计下引入高斯先验
B.产出更interpretable的model
C.防止overfitting
D.产出sparsity的model
答案: A。MAP预计中引入高斯先验,相当于添加L2正则化。
数学
1.(奇虎360)5次同余式x^5=9mod41的解有哪些?
2.(奇虎360)确定以下的序列哪些不是图的序列?
A.(7,6,8。3。8。5)
B.(6,3,3,2。2)
C.(4,4,2,2,4)
D.(3,2,0,1,5)
数据库
1.(唯品会)数据库关系模型范式解决的主要问题是什么?
參考答案:第一范式(无反复的列) 定义:数据库表的每一列都是不可切割的原子数据项,而不能是集合,数组。记录等非原子数据项。
假设实体中的某个属性有多个值时。必须拆分为不同的属性 通俗解释:一个字段仅仅存储一项信息 eg:班级:高三年1班。应改为2个字段,一个年级、一个班级。才满足第一范式 不满足第一范式。
第二范式(属性全然依赖于主键) 定义:满足第一范式前提,当存在多个主键的时候,才会发生不符合第二范式的情况。
比方有两个主键,不能存在这样的属性,它仅仅依赖于当中一个主键。这就是不符合第二范式 通俗解释:随意一个字段都仅仅依赖表中的同一个字段 eg:比方不符合第二范式
学生证 名称 学生证号 学生证办理时间 借书证名称 借书证号 借书证办理时间
改成2张表例如以下:学生证表
学生证 学生证号 学生证办理时间
借书证表:
借书证 借书证号 借书证把你拉时间
第三范式(属性不能传递依赖于主属性) 定义:满足第二范式前提,假设某一属性依赖于其它非主键属性。而其它非主键属性又依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。 通俗理解:一张表最多仅仅存2层同类型信息 eg:爸爸资料表,不满足第三范式
爸爸 儿子 女儿 女儿的小熊 女儿的海绵宝宝
改成 爸爸信息表:
爸爸 儿子 女儿
女儿信息表
女儿 女儿的小熊 女儿的海绵宝宝
使用范式的主要目的是为了降低数据冗余,消除插入异常,更新异常,删除异常。另外从程序设计的角度范式把数据模式做到了高内聚低耦合让数据组织的更加和谐。在数据库设计中应尽量满足最高范式。可是应用的范式等级越高,查询时须要连接的表就越多,这样会添加了查询的复杂度。降低了数据库查询性能。为了提高数据库的运行效率,经常须要降低范式标准:适当添加冗余。达到空间换时间的目的。