互联网公式笔试中经常遇到的问题(转)

本文详细解析了C++中结构体的字节对齐规则,包括不同类型的内存占用、32位与64位系统下的差异,以及如何计算结构体的大小。此外,还介绍了内存管理中的堆和栈的区别,Linux系统的文件权限设置,以及缓存设计的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



互联网公式笔试中经常遇到的问题

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;
 };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23


分析:在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位操作系统:

类型占字节数
char1个字节(固定)
(即指针变量)4个字节(32位机的寻址空间是4个字节)
short int2个字节(固定)
int4个字节(固定)
unsigned int4个字节(固定)
float4个字节(固定)
double8个字节(固定)
long4个字节(VS下验证是4个字节)
unsigned long4个字节(变化,其实就是寻址空间的地址长度数值;VS下验证是4个字节)
long long8个字节(固定)


64位操作系统:

类型占字节数
char1个字节(固定)
(即指针变量)8个字节
short int2个字节(固定)
int4个字节(固定)
unsigned int4个字节(固定)
float4个字节(固定)
double8个字节(固定)
long8个字节
unsigned long8个字节(变化,其实就是寻址控件的地址长度数值)
long long8个字节(固定)

除了与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/delete容易产生内存碎片,栈没有这个问题

答案: 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);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16


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).隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。



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:爸爸资料表,不满足第三范式

爸爸 儿子 女儿 女儿的小熊 女儿的海绵宝宝



改成 爸爸信息表:

爸爸 儿子 女儿

女儿信息表

女儿 女儿的小熊 女儿的海绵宝宝



使用范式的主要目的是为了减少数据冗余,消除插入异常,更新异常,删除异常,另外从程序设计的角度范式把数据模式做到了高内聚低耦合让数据组织的更加和谐。在数据库设计中应尽量满足最高范式,但是应用的范式等级越高,查询时需要连接的表就越多,这样会增加了查询的复杂度,降低了数据库查询性能,为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到空间换时间的目的。


转载自: 互联网公式笔试中经常遇到的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值