禾赛面经分享

前言

    禾赛的linux开发工程师(实习),base是上海,以下是面试遇到的一些问题。

题目与答案

C语言部分

  1. static关键字的作用

static修饰局部变量时:①改变了其存储位置,存储在静态区;②同时改变了其生命周期,为整个源程序,因此它只被初始化一次,若没显式初始化则自动初始化为0。
   
static修饰全局变量时:改变了其作用域,只可以被文件内所用函数访问。
   
static修饰函数时:改变了其作用域,只可被这一文件内的其它函数调用。


  1. 传入函数的时候,指针如何传递?

在C语言中,指针可以通过值传递给函数。当你传递一个指针给函数时,你实际上是传递了该指针的拷贝,但这两个指针(原始指针和拷贝的指针)都指向同一个内存地址。


  1. 假设如下所示传递指针,会不会有问题
func(int* p) {
	p[0] = 0; p[1] = 1;
}

int * a;
func(a);

这个会访问未分配的内存,因为传入的是一个指针,然后在函数内解引用的时候用到了当前地址的后一个位置,而这个位置是未定义的,因此这个会发生错误,以下是实验结果

在这里插入图片描述

  1. 编译的过程

预处理 --> 编译 --> 汇编 --> 链接


  1. 静态链接和动态链接的区别

静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时


  1. 由gcc编译的C语言程序占用的内存分为哪几个部分
区名功能
栈区(stack)存放函数的参数、局部变量。
堆区(heap)提供程序员动态申请的内存空间。
全局(静态)区(static)存放全局变量和静态变量,初始化不为0的全局变量和静态变量、const型常量在一块区域(.data段),未初始化的、初始化为0的全局变量和静态变量在相邻的另一块区域(.bss段)。
程序代码区存放函数体的二进制代码和字符串常量。

  1. 什么是内存泄露

内存泄漏(Memory Leak)指的是在程序运行过程中,动态分配的内存没有得到及时释放,从而导致系统内存的消耗随着程序运行时间的增加而不断增加的现象。简单来说,就是程序在申请内存后,未能适时地释放已申请的内存空间,造成系统内存的浪费,严重时会消耗完系统内存,导致程序卡顿、崩溃或者影响到其他程序的运行。
内存泄漏通常发生在以下几种情况:

  • 常驻内存的程序:这类程序由于一直运行,如果不正确地管理内存,就容易造成内存泄漏。
  • 频繁分配和释放内存的程序:在反复申请和释放内存的过程中,如果存在未被正确释放的内存块,也会导致内存泄漏。
  • 使用了动态分配的内存,但忘记释放:例如,在C或C++中,使用malloc、calloc、realloc或new等函数动态分配内存后,如果没有相应的free或delete操作来释放内存,就会发生内存泄漏。
  • 循环引用:在某些高级语言中,如Java或C#,如果对象之间存在循环引用,并且这些对象没有其他引用指向它们,垃圾回收器可能无法正确地回收这些对象,从而导致内存泄漏。
  • 全局变量或静态变量:这些变量在程序整个生命周期中都存在,如果不当使用,也可能导致内存泄漏。
  • 资源泄露:除了纯内存泄露外,还有资源泄露的概念,比如文件句柄、数据库连接、网络连接等没有适时关闭,这些也可以视为一种广义的内存泄露。

  1. 什么是段错误,发生段错误的原因是什么

段错误(Segmentation Fault)是计算机程序中一种特定的运行时错误。它发生在程序尝试访问的内存地址并不属于其地址空间,或者程序试图以不允许的方式(如写入只读内存)访问内存时。简单来说,就是程序试图访问一个它不应该或不能访问的内存区域。
   
发生段错误的原因有多种,主要包括以下几点:

  1. 指针误用:
  • 未初始化指针:如果指针在使用前没有被正确初始化,它可能指向任意内存地址,导致段错误。
  • 指针已被释放或失效:如果一个指针指向的内存已经被释放(如使用free函数后),或者指针因其他原因失效,再次访问该指针将导致段错误。
  • 指针越界:例如,数组下标越界访问,此时指针可能指向不属于程序的内存区域。
  1. 访问不可访问的内存空间:
  • 试图访问内核空间或其他受保护的内存区域。
  • 访问不存在的内存地址,可能是由于计算错误或逻辑错误导致的非法地址。
  1. 试图写入只读内存空间:例如,程序的代码段通常是只读的,如果尝试向代码段写入数据,将触发段错误。
  2. 栈溢出:这通常发生在函数递归调用过深时,导致栈空间耗尽,并可能覆盖到其他内存区域,从而引起段错误。

嵌入式相关

  1. 说一下I2C通信的流程

这个可以见我的博客:嵌入式驱动学习第七周——I2C子系统,只需要看主机和从机通信部分


  1. I2C有两根线SCL和SDA,说一下发送开始信号时这两根线的电平情况:

SCL高电平,SDA出现下降沿


  1. I2C的死锁有没有尝试过,发生的原因是什么,如何避免

数据线在等待时钟线的下降沿, 时钟线在等待数据线的高电平, 二者等待的条件一直不成立, 最终造成死锁。
  
避免I2C死锁:

  • 要避免I2C死锁,需要在设计和实现阶段就充分考虑和预防潜在的问题。合理规划通信流程、设置时序参数、处理错误和异常情况,以及遵循设备的规范和建议,都是确保I2C通信稳定性和可靠性的重要措施。

I2C产生死锁的原因是什么、避免、解决I2C死锁


  1. linux发生死锁的条件

(1)死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程将无法向前推进。

(2)原因:①系统资源不足。②资源分配不当。③进程推进的顺序不合适。
   
产生死锁的条件:
(1)互斥条件:一个资源每次只能被一个进程使用,其他进程只能等待。
(2)请求与保持条件:进程已经获得至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时该进程被阻塞,但对已获得资源依然保持不放。
(3)不可剥夺条件:进程所获得的资源不能被其他进程剥夺,只能被自己释放。
(4)循环等待条件:若干进程形成首尾相接循环等待资源的关系。


  1. 如何解决死锁

解决死锁:
(1)预防死锁:通过设置一些限制条件,去破坏产生死锁的必要条件。
(2)避免死锁:在资源分配过程中,使用某种方法避免系统进入不安全的状态,从而避免发生死锁。
(3)检测和解除死锁:允许死锁的发生,但是通过系统的检测之后,采取一些措施,将死锁清除掉。


  1. linux的调度算法熟不熟悉,说一说linux调度算法

(1)SCHED_OTHER分时调度策略;

(2)SCHED_FIFO实时调度策略,先到先服务。

(3)SCHED_RR实时调度策略,时间片轮转。


  1. 如何避免死锁

(1)破坏“请求与保持条件”:
①静态分配,即每个进程在开始执行时就申请它所需要的全部资源:
②动态分配,即每个进程在申请所需要的资源时它本身不占用系统资源。
(2)破坏“不可剥夺条件”:一个进程在阻塞等待期间,其占有的资源被隐式释放后被其他进程使用,而阻塞等待的资源只有获得所有需要的资源才能重新启动。
(3)破坏“循环等待条件”:采用资源的有序分配,将所有资源进行编号,紧缺的资源采用 比较大的编号,一个进程只有获得较小编号的资源才可以申请较大编号的资源。


  1. linux内核中,进程的几种状态

在这里插入图片描述

(1)就绪态:所有运行条件已就绪,只要得到了CPU时间就可运行。

(2)运行态:得到CPU时间正在运行。

(3)僵尸态:进程已经结束了但父进程还没来得及回收。

(4)等待态:包括浅度睡眠跟深度睡眠。进程在等待某种条件,条件成熟后即进入就绪态。浅度睡眠时进程可以被信号唤醒,但深度睡眠时必须等到条件成熟后才能结束睡眠状态。

(5)暂停态:暂时停止参与CPU调度(即使条件成熟),可以恢复。


  1. 说一下linux的中断机制
  • 中断控制器接收中断信号并识别中断号。
  • 控制器通知CPU,CPU关中断、保存断点和识别中断源。
  • 根据中断向量表跳转到对应的中断服务程序。
  • 保护现场,即保存当前栈指针和一些寄存器的状态,确保中断服务程序结束后能恢复到原来的状态。
  • 执行中断服务程序,处理中断事件。
  • 恢复现场,返回断点,并重新打开中断。

  1. linux中断分为哪三部分

Linux中断由中断向量表、中断处理子程序和中断请求三部分组成,它们共同协作以处理系统中发生的中断事件


  1. phy和mac的区别

功能上的差异:

  • PHY(物理层芯片):主要实现物理层的功能,是网络结构中的最底层。它负责发送和接收以太网的数据帧,可以检测到网络上是否有数据在传送,并处理数据发送前的准备工作,如数据编码和模拟信号的转换。在发送数据时,PHY会将数据从并行转化为串行流数据,再按照物理层的编码规则将数据编码,然后通过模拟信号将数据发送出去。此外,PHY还负责处理冲突检测等任务。
  • MAC(介质访问控制层芯片):主要实现数据链路层的功能,包括MAC子层和LLC子层的功能。MAC从PCI总线收到IP数据包(或其他网络层协议的数据包)后,会将其拆分并重新打包成特定大小的帧,这个帧里面包括了目标MAC地址、源MAC地址和数据包里的协议类型。MAC还负责处理介质访问控制,确保数据在传输过程中的准确性和效率。

数据传输流程的区别:

  • 在数据传输过程中,MAC层首先处理数据包,将其拆分并重新打包成帧,然后通过PHY层进行发送。PHY层在接收到MAC层传来的数据后,会进行一系列的处理,如增加检错码、数据并行转串行、编码和模拟信号的转换等,最终将数据发送出去。在接收数据时,PHY层负责解码模拟信号并将数字信号传送出去,而MAC层则负责处理接收到的帧数据。

信号处理的区别:

  • PHY芯片主要处理模拟信号,负责信号的解码和转换,将解码后的数字信号传送出去。它不对数字信号进行任何处理,即使一帧有问题的数据也会如实转发出去。而MAC芯片则主要处理帧数据的内容,如更新MAC地址列表等。

  1. phy和mac地址

PHY地址:

  • PHY芯片的地址或物理连接点的标识,负责处理物理层的信号转换和数据传输

MAC地址:

  • 物理地址或硬件地址,是一个网络设备在网络层面的唯一标识符

手撕题

最后是一道手撕题,共享屏幕后,打开leetcode,选了一道字符串题,是leetcode38:外观数列

一道中等偏下题,按题意写就行了

  • 29
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值