8/20 面试题
问题一 :c语言中指针数组与数组指针的区别
指针数组
1>本质上是一个数组,只是每个数组元素都是一个指针变量
2>定义格式:数据类型 *数组名[数组长度];
数组指针
1>本质上是一个指针,用于存储整个数组的起始地址,
2>对于数组指针而言,每偏移一个单位,内存就会偏移一整个数组的容量的大小
3>数组指针一般用于二维数组,二维数组的数组名,本质上是一个数组指针常量
4>定义格式:数据类型 (*数组指针名)[常量];
问题二 :结构体字节对齐
结构体的字节对齐遵循两个原则
1>结构体在给每个成员分配内存空间前对按照数据类型对齐一次
2>结构体在给每个成员分配完内存空间后会整体对齐一次
32位系统以(最大字节的成员,4)对齐
64位系统以(最大字节成员,8)对齐
问题三:TCP和UDP的区别
TCP-------的特点是稳定
1>TCP是面向连接的,可靠的传输方式
2>在传输过程中,数据无失序,无重复,无丢失,无误
2.1>TCP会为每个数据包编号,这个编号就叫做序列号
2.2>每个序列号都需要一个应答包应答,如果没有应答就会一直重复发送上面的包直到正确为止
3>TCP在传输速率低,资源消耗大
4>数据收发是不同步的
4.1>TCP为了提高传输速率会将多个较小且时间间隔短的数据包沾在一起发送,这就是沾包现象
5>应用场景:对传输质量要求比较高以及出阿叔大量数据的通信、例如账号密码的登录,大文件的下载
UDP
1>UDP是面试无连接的,不保证可靠性的,尽最大可能的传输的协议
2>在传输过程中,数据可能会失序,丢失,重复等
3>UDP传输效率高,实时性高
4>收发是同步的,不会沾包
5>UDP在传输过程中规定了传输的最大长度,多出部分直接忽略删除
5>应用场景:发送小尺寸的,在接收到数据给出应答比较困难的情况下,例如:广播,通讯软件的音视频
问题四:同步通信和异步通信的区别
同步通信:发送和接收在同一时间进行,发送方需要等待响应(阻塞)
异步通信:发送和接收可以在不同时间进行,发送方不需要等待响应(非阻塞)
问题五:谈谈对多线程的理解
线程也称轻量版的进程,是进程的一个执行路径。
线程是任务调度的最小单位。
每个进程都至少有一个线程。
线程操作消耗内存较小,效率较高。
线程还有同步互斥机制:对于线程同步问题,有两个机制完成:无名信号量和条件变量;
对于线程互斥问题,采用互斥锁来解决。
线程允许多并发执行,多个线程可以共用一个进程
多个线程释放资源时,可能会发生死锁
问题六:大小端验证
1>不同的主机存储多字节整数时,由于cpu的架构不同,存储方式也不同大致分为两类
大端存储:地址低位存储数据的高位
小端存储:地址低位存储数据的地位
2>验证方式:使用指针或者共用体
问题七:谈谈互斥锁
1>互斥锁的本质是一个特殊的临界资源,该临界资源在同一个时刻只能被一个线程所拥有,当一个线程试图去锁定被另一个线程锁定的互斥锁时,该线程会阻塞等待,直到拥有互斥锁的线程解锁了该互斥锁
2>与互斥锁有关的API有
2.1> 创建互斥锁 pthread_mutex_t mutex;
2.2>初始化互斥锁 pthread_mutex_init(&mutex,NULL);
2.3>获取锁资源 pthread_mutex_lock(&mutex);
2.4>释放锁资源 pthread_mutex_unlock(&mutex);
2.5>销毁锁 pthread_mutex_destroy(&mutex);
3>当多个互斥锁被不同的线程以不同的顺序获取时,很容易发生死锁
3.1>死锁产生的条件
1>互斥条件:资源不能被多个线程共享,在同一时刻只能被一个线程所拥有
2>持有和等待条件:每个线程都持有至少一个资源,并且都在等待别的线程所持有
的资源
3>不可抢占条件:一个资源不能强行从一个线程抢占到另一个线程,只能等该线程
释放该资源
4>循环等待条件:存在一个线程(多个线程的集合){p1,p2,p3}p1在等待p2持有的资源
p2等待p3持有的资源,p3等待p1持有的资源
3.2>如何避免死锁
避免持有和等待:尽可能让线程在开始执行前一次性获取所有必需的资源。
资源排序:规定一个全局顺序来获取资源,并且强制所有线程按这个顺
序获取资源。
- 使用超时:在尝试获取资源时使用超时机制,这样线程在等待过长时间
后可以放弃,回退,并重新尝试。
- 检测死锁并恢复:运行时检测死锁的存在,一旦检测到死锁,采取措施(如
终止线程或回滚操作)来解决。
问题八:共享内存的特点
1>共享内存表示的是多个进程共享一个外部的物理内存,效率比较高
2>共享内存具有时效性,存放到共享内存区域中的数据,如果不及时读取,下一次写入后,前面的数据会被覆盖
3>共享内存的操作不是一次性的,写入共享内存中的数据,即使读取出去后,依然存在于共享内存中,直到下一次被覆盖
问题九:讲一下c中的指针
1>指针能够从地址的角度,找到内存中的数据,而不是以变量的角度去找,效率较高
2>指针:就是内存地址编号
问题十:gcc编译四步
1>预处理
头文件的展开,简单的宏替换,删除注释
2>编译
检查语法错误,没有语法错误生成汇编文件
3>汇编
生成不可执行的二进制文件
4>连接
链接到库函数,生成可执行的二进制文件
问题十一:谈一下对soket的理解
sfd = socket(); //创建一个用于连接的套接字文件描述符
bind(); //为服务器套接字绑定ip地址和端口号,为了让客户端额能够找到服务器
listen(); //将服务器套接字设置成被动监听状态,用于接收客户端的连接请求
newfd = accept(); //阻塞等待客户端的连接请求,如果有客户端发来连接请求,创建一个新的用于通信的套接字文件描述符
while(1) { send\recv\read\write; //数据收发工作 }
close(); //关闭套接字、关闭监听
问题十二:HTTP协议和TCP协议和UDP协议之间的关系
HTTP是应用层协议,TCP是传输层协议,两者的联系是BS模型,HTTP需要TCP来传输其封装的数据,TCP也能保证HTTP相关的数据的完整和正确
问题十三:IP地址和子网掩码如何决定网卡所在的网段
使用IP地址&子网掩码 得到所在网段
问题十四:计算机网络中的OSI七层模型和TCP/IP四层体系结构
七层模型从上到下:应用层 表示层 会话层 运输层 网络层 数据链路层 物理层
四层模型从上到下:应用层 运输层 网际层 网络接口层
问题十五:数据结构中栈和队列的区别
栈和队列都是操作受限的线性表,栈只允许在同一端操作,不能在中间进行操作,栈是先进后出,队列的删除和插入需要在异端操作,是先进先出的,总的来说就是栈的操作在同一端进行,队列中的删除和插入必须在异端进行
问题十六:数据结构中顺序表和链表的区别
顺序表通常使用数组实现,链表通常使用若干个节点组成;
顺序表访问速度较快,链表访问速度较慢;
顺序表插入元素或删除元素需要移动大量元素,链表只需改变它的相邻节点指针就可以了;
顺序表通常在栈上分配内存,而链表在堆上分配内存;
顺序表实现相对简单,链表实现相对复杂;
问题十七:TCP的三次握手和四次挥手
- 第一次握手:客户端发送SYN包(SYN=1, seq=0)给服务器,并进入SYN_SENT状态,等待服务器返回确认包。
- 第二次握手:服务器接收到SYN包,确认客户端的SYN,发送ACK包(ACK=1 , ack=1),同时发送一个SYN包(SYN=1, seq=0),并进入SYN_RCVD状态。
- 第三次握手:客户端接收到服务器的SYN包,以及ACK包,进入establish状态,同时向服务器发送ACK包(ACK=1, ack=1)。此时三次握手包发送完毕,服务器也进入establish状态
- 第一次挥手,主动关闭方发送一个FIN包(FIN=1, seq = u)给被动方,进入FIN_WAIT_1状态;
- 第二次挥手:被动方接收到FIN包,给主动方发送一个ACK包(ACK=1, ack=u+1);并进入CLOKSE_WAIT状态。主动方接受到ACK包后,进入FIN_WAIT_2状态。如果有数据没有发送完毕,则继续发送,直到发送完毕为止;
- 第三次挥手:被动方发送一个FIN包(FIN=1, seq=w),进入LAST_ACK状态.
- 第四次挥手:主动关闭方收到FIN包,回复一个ACK包(ACK=1, ack=w+1)。被动关闭方收到主动关闭方的ACK后关闭连接。
问题十八:指针和指针变量是什么
指针是一种数据类型,而指针变量是这种类型的实例;
指针变量存储的是一个内存地址,而指针定义了指针变量可以存储哪一种指针类型的内存地址;
问题十九:共享内存和消息队列的优缺点
共享内存:
优点:提供了最快的IPC之一,实施起来相对方便,访问速度快;
缺点:需要使用额外的同步机制来避免竞态条件和数据不一致,不当的使用可能使内存泄漏。
消息队列:
优点:提供了数据封装,每个消息都可以包含不同的数据和优先级;本身提供了同步机制,避免竞态条件;
缺点:比共享内存更复杂;消息可能会延迟;对资源有限制