kmp
这个时候p[i]!=p[j+1],数组不匹配时,执行j=next[j]语句,因为不匹配,这时候会让j进行后退,直到j后退到0。
kmp的代码如下
123456789101112131415161718//子串和长串下标从1开始bool kmp(char *s,int l1,char *p,int l2){ /*求next数组*/ for(int i=2,j=0;i<=l1;i++){ while(j&&p[i]!=p[j+1]) j=next[j]; if(p[i]==p[j+1]) j++; next[i]=j; } /*进行字符串配对*/ for(int i=0;i<l1;i++){ while(j<l2&&s[i]==p[j+1]) j++; if(j==l2){ cout<<"匹配成功"<<e ...
gdb
gdb调试程序调试二进制1gcc -g test.c
调试core设置生成core文件
1ulimit -c unlimited
1gcc a.out corename
调试正在执行的程序1gdb -g processid
常用调试命令1list
1run
1next
1stept
1break 行号/函数名
1watch 变量名
1print &a
1info breakpoints
1info watchpoints
1set (var=value)
ui界面
1layout [src asm split]
layout src 源代码
layout asm 汇编代码
linux系统的启动过程
BIOS和启动区CPU中的程序计数器寄PC中存放着CPU下一条执行指令的地址,在计算机通电后CPU会访问PC寄存器中的地址。英特尔的芯片PC寄存器中的初始值为0xFFFF0,这意味着在计算机通电后CPU会执行0xFFFF0这个地址空间中的地址。我们把这块地址空间中存放的程序叫做BIOS(basic input output system)。
Bios程序是硬件厂商写好的,无法改变。BIOS中的程序做的事情是将硬盘0盘0到1扇区的512字节的内容到内存0x7c00中。硬盘的0盘0道1扇区这块区域又叫做启动区MBR(Master Boot Record,主引导记录),启动区最后两个字节分别是0x55和0xaa,这是BIOS识别启动区的标志。
总结一下在计算机通电之后,CPU执行BIOS程序,BIOS搬运启动区代码到内存0x07c00中。
bootsect.s在linux0.11中,启动区的源码文件名为bootsect.s,它将被编译为二进制程序,存放在硬盘的0盘0道1扇区中,作为MBR。
当BIOS搬运完启动区的代码到内存0x7c00后,CPU将执行启动区的bootsect程序
让我们来 ...
git
提交代码到github
创建本地仓库
1git init
追踪本地文件
1git add .
提交修改
1git commit
添加远程仓库
解决分支冲突
推送代码到远程仓库
分支操作如果子分支会继承父分支中的内容,兄弟分支中的内容是独立的
创建分支1git branch module_a
module_a中的内容和main中的内容是独立的
创建子分支1git branch <子分支> <父分支>
切换分支1git checkout module_a
合并分支现在我们需要将fun1分支合并到父分支上
1git merge <分支名>
上面这个命令将某个分支合并到当前分支
解决冲突推荐使用merge而不是rebase
fun1和fun2两个分支都对merge.txt进行了修改,且内容都不一样
这个时候执行合并操作,git会对文件进行箭头标记,表示冲突的部分,这个时候需要我们手动修改内容,在将冲突文件添加到跟踪
12git add merge.txtgit commit -m "finish merge merg ...
队列
队列是一种数据结构
多线程并发
fork函数调用过程1static inline _syscall0(int,fork)
_syscall0是一个宏实现,实现了可复用的函数模板
123456789101112#define _syscall0(type,name) \type name(void) \{ \long __res; \__asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name)); \if (__res >= 0) \ return (type) __res; \errno = -__res; \return -1; \}
这里fork可转化为
123456789101112int fork(void) { volatile long __res; _asm { _asm mov eax,__NR_fork _asm int 80h _asm mov __res,ea ...
作业调度算法
PCB进程控制块PCB(process control block)称为进程控制块。
一个程序并不是从头到尾一次执行的。进程控制块可以保存进程的上下文。
12345678910111213141516171819202122232425262728293031323334//进程控制块struct task_struct {/* these are hardcoded - don't touch */ long state; /* -1 unrunnable, 0 runnable, >0 stopped */ long counter; long priority;/*优先级*/ long signal; struct sigaction sigaction[32]; long blocked; /* bitmap of masked signals *//* various fields */ int exit_code; unsigned long start_code,end_code,end ...
signal
信号信号的位置:/usr/include/signal.h
信号的分类
标准信号/不可靠信号:信号标识符1-32,不处于信号队列中,只能接收一次
实时信号/可靠信号:信号标识符32-64,同一信号可以发送多次,被多次接收,存储在sigqueue中
信号的特点
不可预测/随机性
传送数据简单,信号描述符
信号的状态
generation
delivery
信号的产生
键盘快捷键
系统调用函数
内核产生:硬件异常,被除数为0信号可以由线程产生,也可以由内核产生,但内核产生的终止信号通常是致命的
信号的响应
默认:SIG_DEF通常是终止
忽略:SIG_IGN
用户自定义
==SIGKILL和SIGSTOP的默认行为不能修改,不能被忽略==
内核在信号中扮演的角色
当操作系统从内核态切换为用户态时,会检测==pending&~blocked==位图,如果位图置1则执行信号处理程序
多线程程序中的信号处理函数
对于多线程程序,kill函数会把信 ...
文件系统
文件描述符元数据inodeinode保存文件的属性,执行块区域
inode并不保存文件名
inode表
inode位图
block块
数据块block一个文件保存在一个或多个块中
保存了文件的内容数据,文件读取的最小单位