栈:是一种可以实现“先进后出”的存储结构。操作仅限于栈的顶部。常应用于实现递归功能方面的场景
堆:是一种经过排序的完全二叉树。其中,节点是从左到右填满的,并且最后一层的树叶都在最左边;每个节点的值都小于(或者都大于)其子节点的值。因为堆有序的特点,一般用来做数组中的排序,称为堆排序。
分配方式
栈:由编译器自动分配和释放的,处于相对较高的地址,其栈地址是向下增长的。
堆:由程序员手动完成申请和释放,地址是向上增长的。
存储内容
栈:主要用于存放函数的参数与局部变量等
堆:具体存储内容由程序员根据需要决定存储数据
生存周期
栈:其生存周期也只在函数的运行过程中,在运行后就释放,并不可以再次访问
堆:动态内存的整个生存期是由程序员自己决定的,使用非常灵活。但必须及时释放它,否则将会导致运行的程序出现内存泄漏等错误。
分配效率
栈:栈内存分配运算内置于处理器的指令集中,它的效率一般很高
堆:由函数库提供,机制复杂(由链表记录空闲内存区域),分配效率比栈要低得多
内存碎片
栈:不会存在这个问题
堆:频繁分配和释放不同大小的堆空间会造成内存空间的不连续,从而造成大量碎片,导致程序效率降低
按顺序入栈的序列,任意元素 e ,比 e 先入栈的元素,并且比 e 后出栈的元素,一定是逆序的。
例: 设栈的入栈序列是 1 2 3 4,则下列不可能是其出栈序列的是( )。 A. 1 2 4 3 B. 2 1 3 4 C. 1 4 3 2 D. 4 3 1 2 E. 3 1 2 4
**解法:**以E选项讲解
e
,这里选择3
3
后出栈的有三个元素 1 2 4
3
先入栈的有两个元素 1 2
1 2
是正序的,而不是逆序的 this指针指向被调用的成员函数所属的对象。本质是一个指针常量,储存了调用他的对象的地址。
用途:
this
指针来区分return *this
特点:
this
。this
始终指向当前对象,静态成员函数属于类。
this
指针是在成员函数的开始前构造,并在成员函数的结束后清除 。和函数的其他参数生命周期一样。
this
指针会因编译器不同而有不同的存储位置,可能是栈、寄存器或全局变量 。编译器在生成程序时加入了获取对象首地址的相关代码并把获取的首地址存放在了寄存器中。
ecx
寄存器传递this
指针。
OSI(Open System Interconnect),开放式系统互联。
-
d
c
b
l
p
s
r
:读权限。
w
:写权限。
x
:可执行权限。
-
:没有权限。
s
:SET位可执行权限。
SUID
:只对二进制文件有效SGID
:对普通文件和目录有效t
:粘滞位权限。Sticky
。在该目录创建的文件或目录只有创建者才有权限删除。
-rwxr-xr-x
:文件类型(普通文件-
),所有者权限(r
读/w
写/x
可执行),所属组的权限(r
读/x
可执行),其它用户权限(x
可执行)
.
),表示该文件带有"SELinux的安全上下文";
+
),表示使用了ACL(Access Control List)权限。
u = user, g = group,o = other, a = all
常见执行Linux命令的格式:命令名称 [命令参数] [命令对象]
arch:显示机器的处理器架构
uname -a:完整地查看当前系统的内核名称、主机名、内核发行版本、处理器类型等信息
uname -r:显示内核版本
echo [字符串 | $变量]:在中断输出字符串或变量提取后的值
date:显示系统时间
cal:显示日历
shutdown -h now:关闭系统
reboot:重启系统
cd /etc:切换工作路径
cd:进入个人的主目录
ls -al:显示目录中的文件信息
pwd:显示当前路径
tree:以树形结构显示目录
mkdir dir1:创建目录
touch file1.txt:创建文件
rm file:删除文件
rmdir dir1:删除目录
rm -rf dir1:强制删除目录下的文件
mv dir1 newdir:移动/重命名一个目录/文件
cp file1 file:复制文件
cp -a dir1 dir2:复制目录
cat -n file1:查看内容较少的文本文件的内容
tac file1:从最后一行开始反向查看文件的内容
more file1:查看内容较多的文本文件的内容
head -n 2 file.txt:查看文本文件的前2行
tail -n 2 file.txt:查看文本文件的后2行
tail -f log.txt:实时查看最新的日志文件
cat file.txt | tr [a-z] [A-Z]:替换文本文件中的字符,tr [原始字符] [目标字符]
wc file.txt:统计置顶文本的行数、字数、字节数
stat file.txt:查看文件的具体存储信息和时间等信息
diff -c file.txt file2.txt:查看文件内容具体的不同
file file.txt:查看文件的类型
tar czvf etc.tar.gz /etc:将/etc目录打包
tar xzvf etc.tar.gz /etc:将文件解压到/etc目录
ln -s file1 link1:创建指向文件/目录的软链接(若被指向的原文件被删除,则相关软连接就变成了死链接)
ln file1 link1:创建指向文件的硬链接(如果删除硬链接对应的源文件,则硬链接文件仍然存在,而且保存了原有的内容)
wget [参数] 下载地址:在终端中下载网络文件
ps -aux:查看系统中的进程状态(短格式和短格式之间是可以合并的,合并后仅保留一个-即可)
top:动态地坚实进程活动于系统负载等信息,查看系统运维状态
pidof sshd:查询某个指定服务进程的PID值
kill 2156:中止某个指定PID的服务进程
kill httpd:中止某个指定名称的服务所对应的全部进程
ifconfig:获取网卡配置和网络状态等信息
uptime:查看系统的负载信息,数值越低越好
free -h:显示当前系统中内存的使用情况
last:查看所有系统的登录记录
history:显示历史执行过的命令
history -c:清空所有的命令
sosreport:手机系统配置及架构信息并输出诊断文档
chmod ugo+rwx dir1:设置目录的所有人u、群组g、其他人o,以读r、写w、执行x的权限
chmod ugo-rwx dir1:删除ugo的rwx权限
insmod led.o:向内核加载模块
文件系统是针对于存储器分区而言的,而非存储芯片。
jffs2
(Journalling Flash FileSystem v2)日志闪存文件系统
主要用于NOR型闪存,不适合容量较大的NAND。
特点:可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等。
缺点:当文件系统已满或接近满时,因为垃圾收集的关系而使jffs2的运行速度大大放慢。
yaffs
(Yet Another Flash File System)
用于NAND型闪存的日志型文件系统。相比jffs2,速度更快,挂在时间很短,内存占用较小。支持跨平台。自带NAND芯片的驱动,可以直接对文件系统操作。
Cramfs
(Compressed ROM File System)只读的压缩文件系统
以分页压缩方式存储,在运行时解压缩。不支持应用程序以XIP(eXecute In Place,片内运行)方式运行。速度快,效率高,文件只读。
Romfs
简单的、紧凑的、只读的文件系统,不支持动态擦写保存,按顺序存放数据。支持应用程序以XIP(eXecute In Place,片内运行)方式运行。
其他
fat/fat32、ext2
Ramdisk
将一部分固定大小的内存当做分区使用。并非一个实际的文件系统,而是一种将实际的文件系统转入内存的机制,并且可以作为根文件系统。可以存放一些经常被访问而又不会更改的文件。
Ramfs/Tmpfs
基于内存的文件系统,工作于虚拟文件系统层(VFS),不能格式化,可以创建多个,在创建时可以指定其最大能使用的内存大小。可以存储一些临时性或经常要修改的数据。Tmpfs在系统重新引导时会丢失所有数据。
NFS
(Network File System)网络文件系统
通过网络共享文件的技术。可以利用该技术,在主机上建立基于NFS的根文件系统,挂载到嵌入式设备,可以很方便地修改根文件系统的内容。
结合ROM和RAM的长处,具备可擦除可编程的性能,不会断电丢失数据,可以快速读取数据。
NOR Flash
NAND Flash
嵌入式平台启动流程
系统从装有启动代码的Nor Flash启动后,初始化对应的硬件,包括SDRAM等,然后将Nand Flash上的Linux 内核读取到内存中,做好该做的事情后,就跳转到SDRAM中去执行内核了,然后内核解压(如果是压缩内核的话,否则就直接运行了)后,开始运行,在Linux内核启动最后,去Nand Flash上,挂载根文件,比如jffs2,yaffs2等,挂载完成,运行初始化脚本,启动consle交互,才允许你通过console和内核交互。至此完成整个系统启动过程。
随机访问存储器,直接与CPU交换数据,也叫内存。可以随机读写,速度很快。断电后数据丢失。
SRAM(Static RAM)
DRAM(Dynamic RAM)
DDR RAM(Double-Data-Rate RAM)
volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错
&
(与)、|
(或)、^
(异或)、~
(取反)、>>
(右移)、<<
(左移)
char cTemp; // 全局变量
void SwapChar1(char* lpcX, char* lpcY)
{
cTemp = *lpcX;
*lpcX = *lpcY;
lpcY = cTemp; // 访问了全局变量,在分享内存的多个线程中可能造成问题
}
void SwapChar2(char* lpcX, char* lpcY)
{
static char cTemp; // 静态局部变量
cTemp = *lpcX;
*lpcX = *lpcY;
lpcY = cTemp; // 使用了静态局部变量,在分享内存的多个线程中可能造成问题
}
void strcpy(char* lpszDest, char* lpszSrc)
{
while(*lpszDest++ = *lpszSrc++);
*dest=0;
}
在实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时,可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。不可重入函数在实时系统设计中被视为不安全函数。
malloc()
或者free()
函数;I/O
函数。auto
)局部变量,写出的函数就将是可重入的;OS_ENTER_KERNAL
;ISR
中做浮点运算是不明智的)。死锁是指多个进程在运行过程中因争夺资源而造成的一种阻塞的现象。
产生死锁的原因:
产生死锁的必要条件:
解决死锁的基本方法:
将带符号位的机器数对应的真正数值称为机器数的真值。