linux c/c++面试知识点整理(六)

51、对称加密算法和非对称加密算法

  • 对称加密算法
           对称加密才用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用解密密钥,这就是对称加密算法,常见的有:DES、IDEA。
  • 非对称加密算法
           非对称加密算法需要两个密钥:公开密钥和私有密钥,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;反之,则用对应的公开密钥解密。非对称加密不适合对文件加密,只适合对少量数据进行加密,典型的应用是数字签名。

52、volatile关键字的作用

       volatile变量是随时可能发生变化的,它告诉编译器,与volatile变量有关的运算,不要进行任何优化,每次读取volatile变量时都重新从内存读取。

53、c++中动态联编和静态联编

       静态联编说的是在编译时就已经确定好了调用和被调用两者的关系;
       动态联编说的是程序在运行时才确定调用者和被调用者的关系,典型的应用是虚函数实现的多态性。

54、深拷贝和浅拷贝

       浅拷贝是指将对象内的数据完全一致的复制;
       深拷贝不是这样,它可以将内部的数据按照需要用特殊的方法拷贝,比如说对象内部有一个动态数组,浅拷贝只拷贝指针,而深拷贝则重新申请空间将数据复制过来。

55、什么是柔性数组?

       数组大小待定的数组就是柔性数组。
       一般结构体的最后一个元素可以是大小未知的数组。

56、库函数和系统调用的区别?

       库函数调用时面向应用开发的,与系统无关,移植性好。
       系统调用是面向底层,偏向硬件,系统内核软中断实现,移植性差,系统调用是用户程序和内核交互的接口,系统调用的过程如下:

  • 执行用户程序
  • 根据glibc的函数实现,取得系统调用号,并执行int$0x80产生中断
  • 进行地址空间的转换和堆栈的切换,执行SAVE _ALL(进入内核模式)
  • 进行中断处理,根据系统调用表调用内核函数
  • 执行内核函数
  • 执行RESTORE_ALL并返回用户模式
    系统调用比库函数调用快。

57、构造函数里面”初始化列表”和”赋值”的区别

       对于内置类型来说,没有区别,对于非内置类型则有区别,如下:
       初始化列表只会调用一次构造函数,而赋值会先调用构造,再调用一次赋值函数,什么情况下只能使用初始化列表:

  • 没有默认构造函数的类;
  • 类中存在const成员或者引用类型的成员(它们只能被初始化);

58、为什么要字节对齐?

       自然对齐:一个变量的内存正好是它长度的整数倍。
       需要字节对齐的根本原因在于CPU的效率问题,假设32位机器上int型变量地址是0x00000002,那么CPU取值时需要访问两次内存,一次是0x00000002-0x00000003的short,然后是0x00000004-0x00000005的short,而如果该int型变量的地址是0x00000003,那么CPU则要访问3次内存,即char-short-char,而如果变量是自然对齐的,则CPU访问一次内存就够了。

	struct stu
	{
		char sex;
		int length;
		char name[10];
	};

sizeof(struct stu) = 20;//结构体中每个数据类型都要对齐
什么情况下需要手动设置对齐:
       1. 设计不同CPU下的通信协议(设计一个结构体,32位和64位都用时)
       2. 编写硬件驱动程序时寄存器的结构
手动设置对齐方式有两种:
       1. 代码里添加预编译标识

#pragma pack(n)
#pragma pack()

       2. GNU编译时

#define GNUC_PACKED__attribut__((packed))

59、浅谈僵尸进程

       僵尸进程:当子进程退出时,父进程没有调用wait函数或者waitpid()函数等待子进程结束,又没有显式忽略SIGCHLD信号,那么它将一直保持在僵尸状态,如果这时父进程结束了,init进程会自动接收这个子进程,为它收尸,但如果父进程是一个循环,不会结束,那么子进程就会一直保持僵死状态。
       进程状态:
僵尸|休眠|不可中断的休眠|运行|停止式跟踪
Z |S |D |R |T
       补救办法:杀死僵尸进程的父进程,让init进程来接手,清理掉子进程这个僵尸进程。
       僵尸进程的状态:一个进程在调用exit()函数结束时,并没有真正的被销毁,而是留下一个称为僵尸进程的数据结构,僵尸进程放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保持一个位置,记载该进程的退出状态等信息。
       避免僵尸进程的方法:

  • 使用signal函数忽略SIGCHLD信号
  • 调用wait或者waitpid()函数
  • fork两次,父进程fork子进程后继续执行,子进程fork一个孙进程后退出,此时孙进程会被init进程接管,避免僵尸进程,当然子进程的退出还是要进行处理的。

60、fork函数浅析

       pid_t fork();
       返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程的进程id,否则,出错返回-1.
       子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。
       注意:子进程拥有的是副本,它跟父进程之间是不共享这些存储空间(但是共享代码段)的,因此子进程拥有独立的地址空间。
       fork可能出错的原因:

  • 当前进程数量已经达到了系统规定的上限;
  • 系统内存不足;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cpp加油站

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

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

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

打赏作者

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

抵扣说明:

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

余额充值