450-深信服面经1

1、拷贝构造函数和赋值函数什么时候用到,需要注意什么问题?

  • 拷贝构造函数:使用已有的对象初始化一个新创建的对象时调用。
  • 赋值构造函数:使用已有的对象对另一个已经存在对象进行赋值的时候调用。

注意:

  • 当类中有指针指向堆区空间时,这两个构造函数需要注意出现“浅拷贝”的问题(两个指针指向了同一块堆区空间,对该块空间进行了两次释放)。

2、extern "c"加和不加有什么区别?

函数变量前面加extern关键字的区别

  • extern外部关键字,extern可以修饰变量或者函数(函数默认被extern修饰);
  • 表示该变量或函数的定义在其他文件中,提示编译器遇到此变量和函数时在其他文件中寻找其定义。

动态链接库DLL库中加extern “C”的作用:

  • 在C/C++混合编程的时候用到,在DLL动态库导出函数名前加上extern “C” 表示该函数使用C语言的方式进行编译。

3、内存对齐原则

什么是内存对齐?

  • 在很多CPU架构下,CPU指令都要求操作内存的起始地址能够被操作的内存大小整除; 满足这个要求的内存访问叫做访问对齐的内存;
  • 一般来说编译器中都会对内存进行自动的对齐。
  • 内存对齐就是对内存中数据存放的排列规则,便于硬件的读取

內存对齐系数:

#pragma pack(n) 来设定变量以n字节对齐方式。


内存对齐规则:

1、结构体第一个数据成员放在偏移量offset为0的地方,以后每个数据成员的对齐按照 #pragma pack指定的数值这个数据成员自身长度中,比较小的进行对齐(到首地址的偏移量,指定的数值需要是这个小的数的倍数)。

2、在数据成员完成各自对齐之后,类(结构或联合)本身也要进行对齐,对齐将按照 #pragma pack指定的数值结构(或联合)最大数据成员长度中(比较小的那个对齐,指定的数值需要是这个小的数的倍数。)

3、字节对齐是编译时决定的,一旦决定则不会在发生变化,绝不会在运行时发生尺寸变化。


为什么进行内存对齐?

  • 平台移植性好;
  • CPU执行效率高;

例1:
在这里插入图片描述
在这里插入图片描述


例2:

以32位系统为例;

代码1:

struct A{
	short a;
	short b;
	short c;
};
 
struct B{
	struct A a;
	char c;
	int d;
};
 
printf("%d\n",sizeof(struct B));//--输出  12

代码2:

struct A{
	short a;
	short b;
	short c;
    char d;
};
 
struct B{
	struct A a;
	char c;
	int d;
};
 
printf("%d\n",sizeof(struct B));//--输出  16

对于代码1:

  • struct A 本来是按照short 2字节对齐的,struct A 本身就是6个字节,但是将他放在struct B中时,是由于struct B中是按照int 4字节对齐,所以需要struct B给struct A 分出2个字节的空间用来凑4字节对齐,这2个字节是由struct B提供的,所以struct B中的成员可以占用,也就是struct B中的那个char可以占用,所以一共是12个字节。

对于代码2:

  • struct A 按照short 2字节对齐,struct A本身的大小是8字节,也就是说struct A最后的那个char后面有1个字节的空间,但是注意,这1个字节的空间是由于struct A自身对齐产生的,是属于struct A的,所以将struct A放入struct B中时,虽然struct B中有一个char,但是没法占用struct A中剩余的那1个字节的空间,只能再分配一个4字节用来存储,存储后剩下3字节又不够存储后面的int了,再分配4个字节用来存储int,所以总计是16个字节。

4、memcpy参数能不能是结构体?

可以!

  • 因为mem开头的都为内存拷贝,可以拷贝任何数据。(结构体拷贝到数组,结构体拷贝到结构体,数组拷贝到结构体都可以)。

6、一个棋盘,有个马,给个起点位置和一个终点位置,怎么去找出最短路径?

回溯法(类似剑指offer–13.机器人的运动范围),只能求出最短路径次数。

7、epoll的水平触发和边缘触发特点及区别?

水平触发(默认模式):

  • 内核如果没有将响应socket对应事件的发送的数据读取完毕(如缓冲区太小),下一次epoll仍然会将这个socket对应的事件添加到响应队列中,直到缓冲区中数据读取完毕。

边缘触发(高速模式):

  • 内核没有将响应socket的事件发送的数据读取完毕,下一次epoll不会再提示这个socket事件,直到下一次有数据写入会再次响应。

结合下面8的阻塞非阻塞可以看出:

  • 不论是阻塞还是非阻塞,在读取数据的时候都需要使用while循环将数据全部读取完毕
  • (LT模式可以不用while但是效果很差,因为不能一次将完整的数据进行处理,需要等下一次响应时才能继续接收剩余部分的数据,所以还是一次用while将数据接收完毕)(因为每次recv接收的不保证使设置的长度,可能会比这个长度要小)。

epoll的ET(边缘触发)模式必须使用非阻塞IO:

因为如果使用阻塞IO:

  • 第一种情况,不使用while将数据全部读取完毕,那么下一个事件到来后读取出来的数据可能是上一次事件剩余在缓冲区中的内容,这样会影响这次事件的处理。
  • 第二种情况,使用while将每次响应事件的数据全部读出,那么最后一次recv的时候就会卡在这里,因为是阻塞的,那么这个线程也就废掉了,只能等待这个客户端下一次发送数据读取才能响应,也就是这个线程只能为这个客户端进行服务。

只要是使用while来保证数据读取完毕,就不能使用阻塞IO。


如果每次都使用while将数据读取完整后一起处理,那么两种模式并没有什么差别;

在如下情况:

  • 如果存在被关注的文件描述符但并没有对这个事件进行处理,那么LT模式下epoll会一直返回该事件的响应,而ET模式下则不会。

8、阻塞和非阻塞的fd的recv或者send的区别?

阻塞模式下:

  • send:等待send函数将所有数据拷贝到发送缓冲区中才返回。
  • recv:如果没有数据就一直等待,当有数据到来时,Recv函数将接收缓冲区中的内容拷贝到应用层buffer中(一定要注意,这里不是全部拷贝完才返回,而是只要有拷贝的数据就进行返回,也就是可能比设置想要接受数据长度要小)。

非阻塞模式下:

  • send:函数立即返回,调用和返回之间尽可能的将数据写入到发送缓冲区中。什么时候发送是由系统决定的。
  • recv:如果没有数据直接返回,如果有数据将接收缓冲区中的内容拷贝到应用层buffer中就返回!(不一定全写完,和阻塞情况一样)。

PS:虽然阻塞和非阻塞Recv接受数据时工作原理类似,但是主要区别在于没有要接收的数据时是否直接返回。

9、udp怎么快速定位失去响应的客户机?

  • 发送一个广播,客户端接收到进行回复;
  • 由于UDP数据包可能丢失,可以发送多次广播,将没有进行一次回复的客户端列为失效客户端。

10、如何在40亿中,数据无序,给出一个数,如何快速找这个数?

问题:

  • 在给定的一台4G的PC机器上实现,一个包含40亿个不重复并且没有排过序的无符号的int整数,给出一个整数,找出给定的某个数 m,是否在文件40亿个数据当中。

需求分析:

  • int类型在C++中的存储占用4个Byte,32Bit;

  • 如果在内存中定义40亿个int类型数组来读取文件,占用大小:(40* 100000000*4/1024/1024/1024)G=14.901G

  • 这已经远远超出了机器的内存限制,这时候常规思路是,将数据存在磁盘,分批读取数据到内存中,但这样就会产生磁盘IO,对于追求速率的我们来讲,这种情况我们不考虑。

对于数据来说,某个数据有还是没有,我们可以用0和1来表示,这正好符合二进制的0 1属性;

我们知道C++中1 int = 4 Byte = 32 Bit;这种情况下,我们需要的内存空间是,(40*100000000/8/1024/1024)M = 476.8!竟然满足了我们的要求。

具体思路:

1个int占4字节即4*8=32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32]即可存储完这些数据(其中N代表要进行查找的总数,tmp中的每个元素在内存在占32位可以对应表示十进制数0~31)

后续为位图算法;(参考https://blog.csdn.net/Edward_LF/article/details/124614606)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
《java面经-百度准入职老哥整理.pdf》是一份关于百度准入职面试的Java面经整理。这份面经是由百度准入职的老哥整理而成,其中记录了一些面试时可能会遇到的问题以及解答方法。 这份面经对于准备参加百度准入职面试的人来说非常有价值。首先,它列出了一些常见的面试问题,涵盖了Java语言的各个方面,包括基础知识、数据结构算法、设计模式、多线程、网络编程等等。通过仔细研究和复习这些问题的答案,可以帮助面试者全面了解Java语言的特性和应用。 其次,这份面经还提供了问题的解答思路和方法,帮助面试者理清思路,正确回答问题。这对于很多面试者来说特别有帮助,因为在面试时有时会遇到一些棘手的问题,有了这份面经的指导,面试者可以更好地掌握应对策略。 不过需要注意的是,面经作为一份参考资料,不能完全依赖于它来准备面试。面试官可能会问一些不在面经中列出的问题,因此考生还是需要自己对Java语言有充分的了解,并能够熟练运用。同时,面试官还会关注考生的沟通能力、解决问题的能力以及对新技术的学习和掌握能力。 总体来说,《java面经-百度准入职老哥整理.pdf》是一份非常宝贵的资料,可以帮助面试者对Java面试中可能会遇到的问题有更深入的了解,提供了解答思路和方法。但记住,面试准备还需要多方面的知识积累和实践经验的积累,才能在面试中展现自己的优势。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liufeng2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值