关于该课程说明

1)本课程目标

通过web浏览器访问服务器,实现登录、注册、数据库操作、远程操控硬件、采集环境信息、远程监控、拍照、图片显示等功能。
将单片机、linux、html、摄像头、数据库等知识点融入到一个项目中。

2)什么群体适合学习该课程?

  1. 急需嵌入式项目经验求职但又动手能力欠缺在校学生、毕业生;
  2. 想转行嵌入式Linux的工程师;
  3. 想拓展知识面但工作繁忙、时间紧张的工程师;
  4. 需要带学生项目实训、毕业设计的高校老师

3)课程特色

  1. 本课程讲解项目来源于实际企业项目,具有极强实战效果;
  2. 涉及知识点比较全面,其中大部分都是从事嵌入式Linux开发工作必须掌握的知识点,可以完善工程师知识体系;
  3. 课程内容设置从简到繁,从浩如烟海的资料中整理出嵌入式Linux最科学的学习脉络、知识体系;
  4. 将项目用到的基础知识点分解成一个个独立实例来讲解,用不到的又很重要的整理了一些不错的文章;
  5. 知识点讲解图文并茂,便于理解
  6. 强有力的技术支持, 帮助初学者、缩短学习时间、少走弯路、少跳坑;

文章目录

一、常见问题

0.修改ubuntu分辨率

terminal输入

xrandr -s 1920x1080

要想自动缩放

vmware 设置如下:

1. 环境解压密码:yikoupeng

yikouepng

2. 虚拟机用户名:peng 密码:1

密        码:1

3. CC2530相关

1. IAR编译提示lisence等错误,

卸载该程序,然后重新用管理员权限安装一遍,包括破解软件也要用管理权限打开

2. IAR安装错误

解决方法:

 Win + R :输入services.msc,进入一个服务窗口,
 找到Windows Modules Installer服务,调成启动和手动,然后重启电脑再安装就好了

3. IAR编译遇到IDATA stack overflow detected错误

在这里插入图片描述
解决方法:
在 Project 中选择 Options,
选择 Linker->Config

随后进行参数配置:
在这里插入图片描述

修改linker configuration file如下:

4. iar编译错误

Error[e46]: Undefined external "?V1" referred in AF

在这里插入图片描述
原因
IAR 中8051版8.20之前创建的项目,移植到8.30之后得到错误。
官方解释原文:
The error happens since the new cstartup file in version 8.30 has been changed to optimize the usage of the virtual register area.
机翻:
由于更改了版本8.30中的新cstartup文件以优化虚拟寄存器区域的使用,因此发生了错误。

解决方法
修改 Number of virtual 为8
在左侧Workspace下的GenericApp右键–>Options。

修改 chipcon_cstartup.s51 文件
用记事本打开 ZStack-CC2530-2.5.1a\Projects\zstack\ZMain\TI2530DB下的chipcon_cstartup.s51文件。
现成文件:chipcon_cstartup.s51

在原文件末尾删除 “END”
把以下代码复制到最后面

;----------------------------------------------------------------;
; Virtual registers						 ;
; =================						 ;
; Below is some segment needed for the IAR ICC C/EC++ compiler   ;
;								 ;
; BREG  : A segment for 8 bit registers for use by the compiler. ;
;         ?B0 is the first register.                             ;
; VREG  : Segment that holds up to 32 virtual registers for      ;
;         use by the compiler. ?V0 is the first register.        ;
; PSP   : Segment containing the PDATA stack pointer (?PSP)      ;
; XSP   : Segment containing the XDATA stack pointer (?XSP)      ;
; 								 ;
;----------------------------------------------------------------;
;----------------------------------------------------------------;

	PROGRAM VIRTUAL_REGISTERS
	PUBLIC  ?B0
	PUBLIC  ?V0
	PUBLIC  ?V1
	PUBLIC  ?V2
	PUBLIC  ?V3
	PUBLIC  ?V4
	PUBLIC  ?V5
	PUBLIC  ?V6
	PUBLIC  ?V7
	PUBLIC  ?V8
	PUBLIC  ?V9
	PUBLIC  ?V10
	PUBLIC  ?V11
	PUBLIC  ?V12
	PUBLIC  ?V13
	PUBLIC  ?V14
	PUBLIC  ?V15
	PUBLIC  ?V16
	PUBLIC  ?V17
	PUBLIC  ?V18
	PUBLIC  ?V19
	PUBLIC  ?V20
	PUBLIC  ?V21
	PUBLIC  ?V22
	PUBLIC  ?V23
	PUBLIC  ?V24
	PUBLIC  ?V25
	PUBLIC  ?V26
	PUBLIC  ?V27
	PUBLIC  ?V28
	PUBLIC  ?V29
	PUBLIC  ?V30
	PUBLIC  ?V31
	PUBLIC  ?PSP
	PUBLIC  ?XSP
	RSEG    BREG:BIT:NOROOT
?B0:
	DS      8

  	RSEG    VREG:DATA:NOROOT
?V0:
	DS      1
?V1:
	DS      1
?V2:
	DS      1
?V3:
	DS      1
?V4:
	DS      1
?V5:
	DS      1
?V6:
	DS      1
?V7:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V7
?V8:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V8
?V9:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V9
?V10:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V10
?V11:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V11
?V12:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V12
?V13:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V13
?V14:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V14
?V15:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V15
?V16:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V16
?V17:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V17
?V18:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V18
?V19:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V19
?V20:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V20
?V21:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V21
?V22:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V22
?V23:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V23
?V24:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V24
?V25:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V25
?V26:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V26
?V27:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V27
?V28:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V28
?V29:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V29
?V30:
	DS      1

  	RSEG    VREG:DATA:NOROOT
  	REQUIRE ?V30
?V31:
	DS      1

	RSEG    PSP:DATA:NOROOT
	EXTERN  ?RESET_PSP
	REQUIRE	?RESET_PSP
?PSP:
	DS      1

	RSEG    XSP:DATA:NOROOT
	EXTERN  ?RESET_XSP
	REQUIRE	?RESET_XSP
?XSP:
	DS      2

	ENDMOD ; VIRTUAL_REGISTERS

	END

5. vmware找不到usb设备

1.虚拟机识别串口
打开 VM10.0 虚拟机软件,但不启动 Linux 系统
VM -> Settings -> (左下角)Add -> Serial Port
选择 use physical serial port on the host
选择在 Window 下的串口编号, 比如 COM3
选择 Connected at power on 完成后启动虚拟机系统。
查看虚拟机右下角是否串口已经连接上,没连接上就手动连接

然后在 linux 程序中使用 ttyS0, 进行通讯. 若不行,则尝试一下 ttyS[0-3]

2.虚拟机识别 USB 转串口
首先 windows 能够识别 USB 转串口(可能需要装驱动)。
设置虚拟机:VM -> Removable devices -> Future Devices USB Serial Converter -> Connect (Disconnect from Host) 即可
若步骤二中没有出现 USB 选项, 则关闭虚拟机中的 linux 系统, 添加过程与配置虚拟机识别串口的添加过程一样.
注意:需要确保 VMware USB Arbitration Service 服务是启动的

VMware USB Arbitration Service 服务启动步骤如下:
点击Windows下的开始->运行,在对话框中输入“services.msc”,点击确定,打开Windows服务管理器。
在服务列表中选中“VMware USB Arbitration Service”,双击打开属性对话框,在选中“启动”项就可以启动VMware USB Arbitration Service服务了
关闭VMware软件,再重新打开,启动虚拟机

查看虚拟机 Linux 系统的 /dev 目录,如果有 ttyUSBx 则说明成功了!若是首个 USB 转串口,则显示为 ttyUSB0, 接着在 Linux 程序中打开设备 ttyUSB0,进行串口通讯。

4. 摄像头刷帧比较慢,解决方案

设置vmware usb设备为3.0

5. web页面提示502

编译cgi程序,然后将*.cgi文件拷贝到/www/cgi-bin下

6. 根目录创建app

touch /app
sudo chmod 777 /app

7. 页面没有环境数据

  1. 首先确认协调器和endpoint烧写的文件是否正确,

  2. 先用 串口工具 xcom 查看串口有没有数据上传
    串口必须是协调器
    还有就是串口不要被vmware抓取

  3. 如果串口有数据,那么让vmware抓取协调器的串口,然后运行主控程序
    主控程序会实时打印接收到的环境数据

  4. 将cgi工程的文件全部编译一遍,然后拷贝*.cgi文件拷贝到/www/cgi-bin下

8. 没给节点发命令它突然自己就蜂鸣器响

主要原因是误码了,优化该功能需要增加字段,通过7e头和尾将信令包含进来,
同时数据帧内增加校验码

9. 烧录失败


检查烧录器是否插好,设备是否被vmware抢占

10.找不到/dev/video0


1) 先用cheese测试摄像头,如果不可以用,
检查vmware是否抓取设备摄像头

2) 检查是否有video1设备

二、项目如何介绍?

该项目基于CC2530+Linux+web,实现远程数据采集、远程设备控制和视频监控等功能

1. 无线传感网

基于TI公司的CC2530 soc实现zigbee组网
协调器采集终端节点环境信息数据,并通过串口发送给上位机主控程序,同时协调器接收上位机通过串口下发的命令,
通过zigbee网络发送给终端节点

涉及到外设包括:LED,key,继电器,beep,人体红外,光敏,烟雾传感器,LCD屏幕

2. 基于Linux主控程序

主控程序通过消息队列接收boa服务器fork的cgi程序下发的设备操作命令,然后分派给串口发送线程和摄像头操作线程,
主控程序的串口接收线程负责从串口解析出有效环境数据并发送给共享内存刷新线程,后者解析出来环境数据然后将最终数据刷新到共享内存

涉及技术:
文件IO、多线程编程、多进程编程、信号量、共享内存、消息队列、互斥锁、条件变量、链表操作、视频流服务器移植、boa服务器移植、

3. web开发

通过一款轻量级嵌入式web server提供网页浏览服务,

实现账号登录、注册,显示环境信息,视频监控,历史图片浏览,远程控制设备,账号信息设置等功能。

涉及技术:
数据库sqlite、html、css、javascript、cgi程序编写、linux目录操作

4. 难点:

1) 数据稳定性

采集的数据如何保证正确上传给上位机?

  • a) 协调器发给上位机的环境数据是按照一定格式上传的,但是可能前后会有乱码,上位机必须能够正确找到头部
    我们在上传的环境数据前面加了几个关键字段,用于匹配头
    还可以在上传环境数据中增加校验位
  • b) 上位机的数据采集线程收到的数据要通过链表发送给环境数据刷新线程 链表 + 互斥锁
  • c) 环境数据刷新线程: 从链表中读取一个节点,解析环境数据,转换成真正需要的值,将数据写入到共享内存中还可以将数据保存下来

2) 网页的命令,如何保证不丢失,按照顺序下发给下位机?

  • a)cgi与主控之间如何保证不丢失
    网页发送的命令,web服务器的cgi程序会提取然后然给主控【cgi与主控的通信是属于进程间通信】
    网页的命令随机的,可能会有高并发(同时有多个网页同时访问web服务器)的可能性,
    通过 信号量+消息队列 发送给主控
  1. 信号量:同一时刻只有一个进程可以访问消息队列
  2. 消息队列,所有的消息他会按照顺序缓存在消息队列中,保证数据不丢失其他任务读走之后,他这个消息就从消息队列中删除了
  • b)主控与串口发送线程【线程间通信】
    主控发给串口发送线程,通过 互斥锁+链表 方式,
    链 表 :线程可以访问统一进程内的所有全局变量,访问效率非常高
    互斥锁 :所有访问链表的线程,都必须申请同一个互斥锁,保护临界资源
    主控他的速度会比串口操作快,所以还必须再用链表再次缓冲,
    串口发送线程每次操作链表,都要先申请互斥锁,然后再读走节点
  • c) 剩下就是zigbee的事情了
    到了zigbee网络里,稳定性由 zigbee + cc2530 确定
  • d) 命令会有误码【endpoint有可能收到一个未知数据,该数据可能并不是由网页发送过来的】
    因为之前方案命令只有一个字节,特别容易出问题
    解决方案:修改命令对应的帧格式
    例如:
   0    1    2    3    4
|----|----|----|----|----|
 0x7e  dev  op  crc  0x7e

增加编码难度

    1. 数据也可能有7E
  • 2)如何找到7e头和尾
    参考
https://mp.weixin.qq.com/s?__biz=MzUxMjEyNDgyNw==&mid=2247498985&idx=1&sn=93241e573ec662b826696535f02f32d8&chksm=f96b8e1dce1c070b6216cea54e8b459a28fe3aea98cd7d8e2337ae208e1be02920078808fcd1&scene=21&token=1832549024&lang=zh_CN#wechat_redirect

3) zigbee干扰

4) 硬件供电问题

指定数据上传的规则,定时上传,休眠省电

5) 高并发问题

找一个支持高并发的web服务器

6) 摄像头

数据速率 H.265
布局在单片机上

7) 主控能不能移植到单片机上

可以的,但是有的功能(数据库,摄像头)要check一下

三、面试常见其他问题汇总

一、 项目问题

1.你能介绍下无线传感网这个项目吗?

介绍项目应该是问的最多的,在介绍时首先要有条理,让别人听得懂,并且讲出在这个项目中你担任了什么角色,做了什么,用了哪些传感器实现了哪些功能,数据是怎样传输的。
示例:
在无线传感网这个项目中,我担任项目负责人的角色。我首先对该项目进行了规划,把该项目分为了三部分:下位机、上位机、web端。其中下位机的硬件部分,由我带领我的师弟来完成,下位机的软件部分,以及上位机的主控程序由我来完成,web端由我同门来完成。
在项目规划好后,我对传感器进行了选型。根据要实现的功能(具体介绍…)我选择了XXXXXX。
终端结点搭载的传感器采集到的数据通过zigbee传送到协调器,协调器通过串口传送到上位机。在上位机,我实现了一个主进程,其中包括五个线程,分为数据上传与命令下发。终端结点采集到的环境数据上传到web端进行显示,web端也可以下发命令到终端节点。
五个线程分别是:(这里可以简略说下,如果面试官让详细介绍五个线程可以仿照以下进行介绍)
① 数据读取线程通过串口读取数据,送入链表中,并给数据上传线程发送条件变量信号。
② 数据上传线程收到信号后从链表中读取数据送入共享内存中,共享内存中数据供web端读取。
③ 在web端与上位机端还有一个消息队列,上位机下发命令送入消息队列中,由命令下发线程从消息队列中取出数据进行甄别,如果是下位机的命令则送入链表中并给下位机线程发送条件变量信号。
④ 下位机线程收到信号后取出命令,并通过串口送入协调器,协调器通过zigbee网络发送到终端结点并执行。
⑤ 在上位机端还有一个摄像头监控,若是摄像头的拍照命令,则由摄像头线程直接取走拍照命令并执行。

在详细介绍后,面试官会根据项目介绍的内容进行提问。主要在以下几个方面:

  1. 串口的使用
  2. zigbee的使用
  3. 进程、线程的知识
  4. 进程间通讯
  5. 线程间通讯的使用、锁的使用
  6. 数据结构相关知识、如链表、队列、数组等
  7. C语言相关知识
  8. 单片机使用、Linux等相关问题

1. 串口的收发处理涉及到几个寄存器?

你能说一下串口的协议吗

2. UART外设某一个数据的发送过程了解吗?

波特率:事先确定好波特率,一般为9600,19200,115200等,代表每秒传输这么多个比特位数(bit)
起始位: 先发出一个逻辑0的信号,表示传输数据的开始。
数据位: 可以是5-8位,一般是8位 小端传输
校验位: 数据加上这一位后,使得1的位数为奇数或者偶数,以此来校验数据传送的正确性。
停止位: 字符数据结束标志 变为1。 可以是1位、1.5位、2位的高电平。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。
空闲位: 处于逻辑1状态,表示当前线路上没有资料传送。

2.数据发送
比如将0x41 即 01000001 发送给PC机
双方约定好波特了(每一位占据的时间)
ARM将原本的高电平拉低,保持1bit时间,表示开始。PC机在低电平开始处计时。
ARM根据数据依次驱动TxD引脚电平发送数据,同时PC依次读取RxD引脚电平获得数据。
数据发送完后发送一个停止位。
1bit 开始位
115200,8n1 代表 波特了115200 8位数据为,没有校验位,1位停止位。

即发送每一个字节数据需要10位。每秒发送115200位,即11520个字节数据

3.zigbee不会受外界干扰吗?数据传输会不会中断?

zigbee能耗低、有大规模的组网能力。在可靠性方面。物理层采用了扩频技术,能够在一定程度上抵抗干扰,MAC应用层(APS部分)有应答重传功能。当ZigBee网络受到外界干扰,无法正常工作时,整个网络可以动态的切换到另一个工作信道上。

4. 下位机用的哪个平台进行开发的?生成编译后的文件是什么格式的?

下位机CC2530部分的开发主要用到IAR,生成编译后的文件是二进制文件.bin。

5.你是根据什么来进行选型的?

(如果写的硬件部分是自己做的,可能会问到这个问题)
结合应用场景、需要实现的功能、成本等,言之有理即可

6.主控程序中视频监控是怎么做的?

(视频监控具体是怎么做的?用的哪些模块?)
(你对这个mjpg_stream有多少了解?可不可以介绍一下这个代码?它的功能是什么?主要是用来做什么的?在你这个项目中起到了一个什么作用?)
摄像头这里主要是移植了mjpg-streamer这样一个视频图像开源库。它可以通过HTTP的方式访问linux上面的兼容摄像头,从而做到远程视频传输的效果。并且从摄像头上采集图像,把他们以流的形式通过IP的网络传输到拥有浏览器的移动设备。
可以获取静态图片、视频流,并且自带了图片定时抓拍的功能。
参数中可以设置帧数,默认30帧、指定视频大小,如320×240,指定画质,默认80,以及输出参数,如端口、网页目录,并且可以设置密码。
自带的功能只能实现单拍,我给实现了连拍

7.视频的流量、速度可以吗?视频分辨率是多少?

就按默认的30帧,分辨率根据网速进行调试的 最后是320×240

8.线程和进程的区别是什么?(高频)

  1. 进程是资源分配的基本单位,线程是程序执行的最小单位,也是处理器调度的基本单位。
    执行程序就会创建一个进程,一个进程中可以创建多个线程。
  2. 进程有自己的独立地址空间,线程共享进程中的数据,使用相同的地址空间。
  3. 线程间通信更方便,同一个进程下的线程共享全局变量、静态变量等数据,而进程间通信需要以通信的方式进行。IPC通信
    4.多线程程序只要有一个线程死掉,线程所在的整个进程也跟着死掉,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己的独立空间地址。
    5.进程切换时,消耗的资源大效率低。所以涉及到频繁的切换时,使用线程要好于进程。如果要求同时进行并且要求共享某些变量的并发操作,只能用线程不能用进程。
    6.线程开销少,但是不利于资源管理和保护,进程开销大,但是能够很好的进行资源管理和保护。

9.进程间通讯有哪几种方式?(高频)

在项目中用的比较多的有哪几种?能简单介绍一下怎么用到吗?
有名管道:fifo 全双工 可在任意进程间使用
无名管道:pipe 半双工、只能在具有亲缘关系的进程间使用
信号:唯一的异步通信方式
信号量:配合共享内存使用,实现同步和互斥
共享内存:效率最高(之间访问内存),需要同步与互斥机制。
消息队列:常用于cs模型中,按消息类型访问,可有优先级。
套接字:用于不同机器间的进程通信。

在项目中主要用到共享内存和消息队列,主要用于上位机和web端的交互。

10. 讲一下共享内存(会问到具体函数)

共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何的数据拷贝。为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间,进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高效率,由于多个进程共享一段内存,因此也需要依靠某种互斥机制,如互斥锁和信号量。
使用步骤:

  1. 创建/打开共享内存
    shmget(key, size, shmflg) key是 ftok的返回值 size是共享内存大小,flg是权限位0777
  2. 映射共享内存,即把指定的共享内存映射到进程的地址空间
    shmat(shmid, shmaddr, shmflg) 要映射的共享内存标识符,将共享内存映射到指定地址,权限位
  3. 撤销共享内存映射 shmdt(shmaddr)
  4. 删除共享内存对象 shmctl(shmid, cmd, buf)

11.你能详细介绍一下消息队列的方式吗? 介绍共享内存和消息队列的区别

消息队列是IPC的一种,由消息队列ID来唯一标识。消息队列就是一个消息的列表,用户可以在消息队列中添加消息、读取消息。消息队列可以按照类型来发送接收消息
12. 两个进程同时对共享内存读写的时候会不会出现一些问题?
使用信号量进行保护
13.linux创建线程的方法是什么?
pthread_create()
pthread_join() 等待回收

14.项目中涉及到多线程吗?有使用锁码?关于锁的使用都是用过什么锁?满足了什么需求?还有哪些锁了解码?

互斥锁、自旋锁、读写锁、条件锁(条件变量)

15.读写锁使用过吗?读写锁的使用场景是什么?

16.互斥锁与读写锁的区别是什么?

读写锁分为读锁和写锁。
在一个线程读的时候,其它线程也可以读,是共享的。
在一个线程写的时候,其它线程既不能读也不能写是互斥的。
互斥锁是互斥的,仅有一个线程可以占用,其它不能获得锁的线程将会睡眠等待。

17.多进程通讯方式有哪些?现在主流的两种不同接口说一下?

18.Linux常用命令用过哪些

19.Linux下调试是怎么调试的?应用程序调试怎么调试的?有用过GDB吗?

20.在这个整个项目中最需要注重的点或者说难点在哪里?

(开放性问题,言之有理即可,准备1-2个)
例:
主要在数据上传部分,要实现数据能上传上去,并且要保证数据正确。
首先,XXXXX
其次,XXXXX

21.回顾一下你这个项目还有哪些地方是可以改进的,如果改进的话可以如何改进?

(开放性问题,言之有理即可,准备1-2个)
结合项目应用场景进行准备

22.这个项目的项目背景是什么? 它是在什么情况下使用的?

结合实际应用场景进行回答,如智能家居、农业园等

23.回顾一下你这个项目还有哪些地方是可以改进的,如果改进的话可以如何改进?

结合应用场景,如:当温度计温度过高时自动下发命令开启风扇等降温系统xxxxxxxx
(开放性问题,言之有理即可)

四、C语言相关问题

1. 引用和指针有什么区别?

(1) 引用不可以为空,指针可以为空
(2) 引用不可以改变指向,指针可以改变指向,指向其它对象
(3) 引用的大小是所指向对象的大小,因此引用只是一个别名,指针是指针本身的大小,四个字节。
(4) 指针使用时要加*,引用可以直接使用
(5)程序为指针分配内存区域,引用不分配内存区域。

2. C语言中有个悬空指针是什么?空指针是什么?

悬空指针:一个指针的指向对象已被删除,就成了悬空指针
野指针:指向不可用内存的指针(没有初始化的指针)。
空指针:没有存储任何的内存地址的指针是空指针,指向NULL

3. 什么是结构体对齐?

许多计算机系统对基本类型数据在内存中存放的位置有限制,要求数据的起始地址需是k(对齐数)的倍数,这样可以提升读取数据的速度。

平台原因:不是所有的硬件平台能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐,是因为为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存访问仅需要访问一次

结构体占用的空间为最大对齐数的整数倍。

4.sizeof() 和 strlen()区别

(1) sizeof()既是关键字也是运算符,strelen()是函数。
(2) sizeof()可以用类型作为参数,也可以是变量名,如果是类型必须加括号,strlen()只能用char*作为参数,而且必须以“\0”结尾。
(3) sizeof()是在编译期的时候计算的,可以通过sizeof(x)来定义数组的维数,strlen()是在运行期计算的,用来计算字符串的实际长度,不是类型占内存的大小。

5.哪个关键字强制结构体对齐?

译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。

6.讲你掌握的关键字

(1) volatile
(2) static
(3) extern
(4) const
(5) sizeof
(6) typedef
(7) struct
(8) register
(9) union

7.const和define的区别是什么?数据类型方面有区别吗?

(1)#define语句只是一个简单的替换,define常量的生命周期止于编译器,不分配内存空间,它存在于程序的代码段。而const常量存在于程序的数据段,并在堆栈中分配了空间,可以被调用、传递。
(2)主要区别: define是没有数据类型的,const修饰的话是有明确类型的,编译器可以对const常量进行类型安全检查,而define不行。

8.typedef和define有什么区别?

typedef和define都是替一个对象取别名,以此来增强程序的可读性。
(1) 原理不同
define是预处理指令,在预处理时进行简单的字符串替换,不做正确性检查,只要在编译已被展开的源程序时,才会发现可能的错误并报错。
typedef是关键字,它在编译时处理,具有类型检查的功能。
(2) 功能不同
typedef用来定义类型的别名,不仅包含内部类型还包括自定义类型,可以起到使类型易于记忆的功能。
define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。
(3) 作用域不同
define没有限定的作用域,只要之前预定义过的宏以后程序中都可以使用。
typedef有自己的作用域。
(4) 对指针操作不同
修饰指针类型时作用不同。define进行宏替换是不含任何意义的替换,仅仅为字符串替换,而用typedef是一种数据类型起的别名,带有一定含义。

9.内存是怎样分区的?

(1) 代码段 通常用来存放程序执行代码的一段区域,通常只读
(2) 数据段(常量区) 通常用来存放程序中已初始化的全局变量和初始化的非0静态变量,属于静态内存分配
(3) bss段(全局区) 未初始化的全局变量和未初始化的静态变量或初始化为0的静态变量,属于静态内存分配
(4) 堆 用来存放进程中被动态分配的内存段
(5) 栈 用来存放程序临时创建的变量

10.使用内存时候使用什么接口?申请内存

malloc

11.malloc一次可以申请多大的内存

malloc需要计算申请内存的大小,可申请的最大内存的具体数值受到操作系统版本、程序本身的大小、用到的动态/共享库数量、大小,程序栈数量、大小的影响。最大可申请的大小大约在2G

12.申请后的内存不释放会造成什么问题?

申请后不释放容易造成内存泄漏,最终导致系统崩溃。

如果重复释放容易把其它程序占用的内存空间给释放掉。

13.结构体的大小怎么算出来的?

所有成员长度之和,再考虑字节对齐,最后的总和。

14.字符串拷贝是哪个接口?

15. 野指针了解吗 如何避免野指针

(1)野指针是指向不可用内存的指针,当指针被创建时,指针不可能自动指向NULL,这时,默认值是随机的,此时的指针称为野指针。
(2)当指针指向的内存被free或delete释放掉时,如果没有把指针设置为NULL,则会产生野指针,因为释放掉的仅仅是指针指向的内存,并没有把指针本身释放掉。
(3)指针操作超越了变量作用的范围。

(1) 对指针进行初始化
(2) 指针用完后释放内存,并将指针指向NULL

16. 结构体struct和union联合体的区别

(1)联合体中所有成员共用一块地址空间 ,即联合体只存放了一个被选中的成员,而结构体中所有成员占用空间是累加的,所有成员都存在。结构体内存空间大小等于所有成员长度之和再加上对齐对齐部分,而联合体占用空间大小等于最长成员的长度在加上字节对齐部分。
(2)对联合体不同成员赋值,将会对其它成员重写,原本成员的值就不存在了,而对结构体不同成员赋值互不影响。

17.C和C++互相调用有用到吗?互相调用情况下该怎样使用?

(1)C++调用C
加上 extern “C” 会指示编译器这部分代码按照C语言进行编译

18.指针在使用时候应该注意些什么事项?

(1)指针定义后要初始化,没有指向时指向NULL。
(2)指针赋值时要保证类型匹配
(3)两个指针最好不用指向同一块内存,一个指针释放会导致另外一个指针成为悬空指针。
(4)释放指针指向的内存后要将该指针指向NULL
(5)指针分配成功后才可以使用,要注意分配后的大小,不要越界。

五、开放性问题

1.有没有遇到什么困难?怎么解决的?

2.有没有感觉压力很大的时候?怎么做的?

3.对未来一到三年规划?

4.从应届生转换的职场人要做哪些准备?或者说做哪些改变?怎样应对?

5.你觉得自己身上哪些品质比较自豪、比较有成就感?你觉得你自己的优势和劣质是什么?

6.你能讲一个你自己的缺点吗?你觉得这一点会对你的工作带来什么影响?

7.未来的就业方向是怎么考虑的?

8.你能分享一件你遇到的困难的一件事吗?

9.在项目中遇到了什么样的问题,是以什么样的思路来解决问题的?

10.通过这个问题,收获到什么样的经验?或者教训心得

Logo

更多推荐