Linux
1.目录结构:
/根
bin boot etc home root lib val ...
命令 内核 配置文件 库
stu 用户名(xiaoming)
main.c mycode 桌面 ...
家目录:/home/stu /home/xiaoming
在当前目录下可以省略当前路径 ./home == home
$普通(只在home中有权限)
#管理员 可切换:sudo su
2.常见操作:
cd ~ 切换到家目录
pwd 显示当前位置
ls 显示当前位置的文件
touch 创建普通文件
mkdir 创建目录文件(文件夹)
cd . 当前
cd .. 上一层
3.文件类型:
- 普通文件
d 目录文件
p 管道文件
l 链接文件
c,b 设备文件
s 套接字文件
4.修改权限:
r 4 只读 w 2 只写 x 1 执行
u g o
- rwx rwx r-x
若要修改权限:
修改权限:
chmod u-x a.txt
chmod g-w a.txt
chmod o+w a.txt
修改为: - rw- r-x rwx
按照权值修改(数字设定法)
chmod 657 a.txt
5.文件复制粘贴移动:
cp: a.c b.c cp: -r mydir1 mydir2 目录文件 -r cp: ../b.c . 相对路径绝对路径均可
rm: a.c b.c 一次可以删除多个 rm: -r mydir2 目录文件 -r
mv: a.c temp 移动(ctrl+v) 目录文件不用 改名字 mv: a.c b.c(将a.c 改为b.c)
6.VIM使用:
命令模式 ——————插入模式——————末行模式
1->2:i,a,o,I,A,O
2->1:Esc
1->3:(输入冒号):
命令模式:
r 修改一个字符 R替换,Esc结束
C 大写,清除光标到行末的内容
cc 清除光标所在的一行的内容,并进入插入模式
x 删除一个字符
末行模式:
wq:退出并保存
q!:退出不保存
q:只退出,前提是未修改文件
w:只保存不退出
set nu 显示行号 set nonu 取消行号
:n 跳转到第n行
gg 跳转到第一行 G 跳转到文件末尾
n yy 复制n行 n dd 剪切/删除n行
p粘贴 u :撤销 ctrl + r 恢复一次操作
?从后往前搜索 /从前往后搜索
/末行模式搜索,n在多个搜索到的位置切换
set hlsearch 设置高亮 set nohlsearch 取消高亮
gcc -o main main.c 生成可执行程序main 运行程序必须写全部路径
cat a.c 将文件打到屏幕上(文件内容少)
cat b.c main.c > flie1 也可以合并文件
cat >aa.txt 写入文件 ctrl d 退出
more passwd 分屏显示,不可反复看
less passwd 可以反复看,分屏显示,q退出
tail/head -3 passwd 显示末尾(开头)几行 默认十行
find 路径 -name 文件名 在系统内查找
grep "hello" main.c 文件查找字符串
-i 不区分大小写 -c 显示有几行 -v 取反 -w 绝对查找 -e 查找多个
l 管道 top 显示终端(每隔一秒刷新)运行 q退出
进程:一个正在运行的程序(操作系统)

管理进程: 讲述描述符|进程控制块|PCB
命令解释器(shell):bash

kill + pid 结束一个正在运行的程序 ctrl + c 可以结束一个前台运行的进程
kill -9 pid 强制结束 -e (所有) -f(fu进程)
ps -ef | (竖线) grep "sleep"
sleep 300 & 放后台,不影响其他命令
jobs 只显示后台运行任务 包括(任务号)
bg %任务号(前台切后台,先停止) fg %任务号(后台切前台) ctrl + z 停止在前台运行的进程
man 帮助手册 :
1.命令 2.系统调用 3.库函数
关机重启:

tar cvf xx.tar a.c passwd -->打包并命名为xx.tar
解压:
tar zxf xx.tar.gz
运行级别: 3级别,文本方式,无图形化界面 5级别,图形界面
由源文件 ———>可执行文件 : 预编译--编译--汇编--链接
-E -S -c -o

makefile文件 ,管理工程,实现自动化的编译
linux 调试程序: GDB命令调试 开发调试版本 -g gcc -o test test.c -g
l 显示代码
b + 行号 加断点
info break 显示断点信息
display i(一直显示i的值)
r 启动程序
p 打印
q 退出
c 继续运行
s 进入函数
finsh 跳出函数
bt 显示当前位置,展示函数的层层位置
ldd 查看可执行程序用到哪些共享库
库文件 ,静态库 ,共享库 (动态链接库)
printf() 库函数
stdio.h -->声明 libxx.a 静态库 :C语言,预先编译好的方法的集合
c库文件 libxx.so 共享库 :
生成静态库 : ar crv libfoo.a add.o max.o
生成共享库 : gcc -shared -fPIC -o libfoo.so add.o max.o
(须把生成的libfoo.so移动到/lib中才能运行,默认在/lib中寻找库) /lib,/usr/lib
使用库foo : gcc -o main main.c -L.(路径名) -lfoo(库名)
静态库和共享库的区别:

-
静态库:编译时合并代码到可执行文件,生成独立程序。优点:部署简单,无外部依赖。缺点:磁盘和内存占用大,库更新后需重新链接。
-
共享库:编译时只记录依赖,运行时动态加载。优点:节省磁盘和内存,库更新后重启即可生效。缺点:部署依赖目标系统有正确版本的库,版本不兼容可能导致运行失败。
int main(int argc , char* argv[] , char* envp[]) 有三个参数
参数个数 参数 环境变量 argv[0] 是程序名称或路径

printf --> 在缓冲区存储(由内核打印到屏幕) 可以强行刷新缓冲区输出到屏幕上
1. "/n" 2.fflush(stdout)
exit(0) ->强行输出 _exit(0) ->不输出

fork:通过复制当前进程来创建一个子进程
fork 的写时拷贝:子进程创建时并不立即复制父进程的物理内存,而是与父进程共享同一份内存并将页面设为只读;当父子任意一方试图修改内存数据时,操作系统才会为该页面真正分配独立空间并复制内容,提升 fork 效率并节省内存,以页为单位拷贝
推迟内存的拷贝(复制),甚至免除

在子进程中: pid = 0;
在父进程中: pid = 子进程的pid > 0
子进程是父进程的副本,但拥有独立的 PID,其余完全相同,仅在fork后接着运行
父子进程同时执行,顺序不确定
父进程的父进程为bash -->好多进程的父进程
父进程一结束就会有提示符
先fork 拷贝,复制 --> 在进行exec替换
僵死进程:子进程先于父进程结束,父进程没有获取子进程的退出码,那么子进程变成僵死进程
孤儿进程:父进程先结束,子进程会被重新分配新的父进程,然后在正常wait
解决方法:父进程调用wait() -->阻塞父进程,子进程结束后再运行父进程

若不采用此,需将退出码右移八位
程序中打印的都是逻辑地址,相对于起始地址的偏移量
文件描述符:open read write close 等方法
1.打开文件 2.读/写 3.关闭文件
stdin 标准输入 -->0 stdout 标准输出 -->1 stderr 标准错误输出 -->2 默认打开这三个
file.txt -->3(自己创的)...
先fork,在打开文件 --> 父子进程有各自的偏移量
先打开文件,在fork --> 偏移量父子进程共享,同时移动文件偏移量




同一个偏移量 父子进程各自的偏移量
替换 : execl ---- >最终都通过 execve 系统调用实现
成功之后 -->不会返回(原进程的代码段已被替换,不可能再执行 exec 之后的代码)

系统调用:
应用程序调用 open() 库函数时,会先将系统调用号 5 存入 eax 寄存器,然后通过 int 0x80 指令触发软中断,从用户空间切换到内核空间;内核根据 eax 中的编号 5 查表,找到并执行对应的内核函数 sys_open(),完成文件打开操作;执行完毕后,内核恢复现场并返回用户空间,最终将返回值传递给应用程序。


系统调用和库函数的区别:
系统调用是操作系统内核提供的底层接口,运行在内核态,用于访问硬件 / 系统资源,开销大、不可移植;库函数是编程语言 / 第三方库提供的封装函数,运行在用户态,通常会封装系统调用,开销小、可移植。
exec -->替换: 没有本质区别,只是传参不同 底层调用execve
fork + exec 产生全新进程


fun 函数是由操作系统内核在信号发生时**自动调用**并传入信号编号作为参数的,而不是由代码直接调用的,所以不需要传参,只是注册了一个函数。
内核会在信号发生时自动传参。(收到信号才会传参)


kill可以执行信号的代号,通过传参,但是kill 9 不可改变,强制杀死
-
kill(pid, sig):向进程号为pid的进程发送编号为sig的信号 -
成功返回 0,失败返回 -1
父进程通过忽略 SIGCHLD 信号,可以让子进程退出后被系统自动回收,避免产生僵尸进程
进程间通信(IPC):管道,信号量,共享内存,消息队列,套接字
>写入管道的数据再内存中,速度快<
通信方式:半双工 此外还有单工,全双工(电话)
创建管道文件 mkfifo,成对出现
1.无名管道:只能用于父子进程或兄弟进程等有亲缘关系的进程 fd[0] 读 fd[1] 写
2.有名管道:可以用于任意两个进程,但需要两个进程同时打开(一个读,一个写)同时操作
管道为空,读操作read()阻塞;管道为满,写操作write()阻塞
关闭写端,read返回值为0;关闭读端,write出发异常(产生信号) //SIGPIPE (13)
信号量同步操作: 0.1二值信号量 3,计数信号量
ipcs 介绍信号量,在运行中可以看到,结束后看不到
ipcrm -s id 删除信号量
PV操作:
两个信号量控制读写一致
【进程间通信(IPC)】函数:

shmctl semctl


并发运行:交替运行 并行:两条线程同时运行
消息队列:
普通消息类型必须 > 0,若type = 0,则不区分消息类型,都可以接收 线程结束对主线程没有影响但主线程结束,其余线程都会结束。可以使用join阻塞,等待线程结束
- 原子操作:不可拆分、中途不能被打断;
i++不是原子操作,底层分读、改、写三步,多线程会互相抢数据、算错值。会导致输出数据与预期不匹配。 - 数据竞争:多线程同时改同一个共享变量,不加锁就会结果错乱、数值偏小。 也可以malloc一个内存空间,存储该线程的变量,让主线程变量的修改不会影响该线程。
- 互斥锁:同一时间只让一个线程进代码段,把多步操作变成逻辑不可打断,解决数据竞争和打印乱序。
- 打印不出 01234 原因:主线程循环跑得太快,子线程启动有延迟,共用同一个循环变量
i,读到的都是被改后的旧值。多个线程抢一个i变量。 - 解决办法:给每个线程单独传参,不共用变量;多线程操作共享数据必须加锁,还要用
pthread_join等线程跑完再退出。


本程序设有2个生产者线程、3个消费者线程,生产者向环形缓冲区放入数据,缓冲区满则阻塞;消费者从缓冲区取出数据,缓冲区空则阻塞,借助信号量实现同步、互斥锁实现临界资源互斥访问,生产与消费总数量相等,线程安全有序运行。先同步,后互斥。
线程,进程内部的一条执行路径 //进程,一个正在运行的程序 //调度,执行的基本单位
(linux多线程及线程同步的方法)
线程同步的方法:互斥锁,信号量,读写锁,条件变量
线程安全:无论调度顺序如何,都能得到正确的结果
创建线程,管理员在内核完成,可以使用多个处理器
多线程的程序执行fork后,子进程只有一条执行路径,fork所在的那条执行路径(线程)
使用线程安全函数:如,将strtok -->strtok_r


必须先执行服务器,在执行客户端,否则链接不成功,在客户端不强调必须绑定(ip+port)
TCP 面向连接可靠的流式服务,UDP 无连接高效快速但不可靠
套接字文件 sockfd = 3 文件类型 在int c = 4,文件类型
三次握手 四次挥手


为什么不是两次?
- 两次握手会有 “半连接” 风险:如果客户端的 SYN 包延迟到达,服务器收到后回复 SYN+ACK,但客户端早已超时重连,服务器会一直等待 ACK,浪费资源。
- 第三次握手本质是让客户端确认服务器的接收能力正常,只有客户端确认收到了服务器的 SYN,连接才正式建立。


-
为什么挥手要四次? 因为 TCP 是全双工的,双方都可以独立发送数据:
- 客户端发 FIN,只是表示 “我不发数据了”,但还能接收数据
- 服务器回复 ACK 后,可能还有数据要发给客户端,所以服务器的 FIN 必须等自己的数据发完再发,这就把 “服务器确认客户端 FIN” 和 “服务器发 FIN” 分成了两步,所以总共四次。
-
为什么客户端要等 2MSL(2分钟)? -->(time wait存在的意义)
- 确保服务器收到了客户端的 ACK:如果服务器没收到 ACK,会重发 FIN,客户端在 2MSL 内还能收到并重发 ACK
- 防止旧连接的报文干扰新连接:2MSL 可以让本次连接的所有报文都在网络中消失,避免后续新建连接时收到旧数据
connect之后开始握手,在接受和发送数据之前
套接字:点分十进制的IP地址+端口号
netstat -natp : 查看本机所有 TCP 连接(监听 / 已连),用数字 IP 端口,同时显示是谁(哪个进程 / 程序)在占用



tcp:可靠性,应答确认,超时重传,可以去重,乱序重排。面向字节流,但会发生粘包问题(粘包:对方发送的多个报文,被一次性收到了):1.加起始结束标记 2. 使用固定长度的报文3. 报头中包含数据的长度。tcp使用滑动窗口,可以进行流量控制//(通信双方都有发送缓冲区和接收缓冲区),点对点连接
udp协议:编程流程 ,无连接,不可靠,数据报服务,不用建立链接,所以可以把客户端或者服务端关闭之后在开启也可以发送,无粘包,发送一次,能接受多少传多少,下一次重新开始

tcp和udp可以使用同一个窗口:会根据自己各自的协议进行区分
- 端口只是逻辑编号,TCP、UDP 是两套独立协议
- 系统内核根据协议 + 端口区分数据,不会混包
访问服务器不传参,默认为/index.html /favicon.ico为网站的图标
lseek,设置鼠标偏移量的移动(也可以求文件大小)
- strcat:只能拼固定字符串,不能用变量 / 数字。
- sprintf:能拼数字、变量,支持格式化拼接。


一、基础网络协议(HTTP/HTTPS)
- 层级与端口
- HTTP:应用层协议,默认端口 80
- HTTPS:加密版 HTTP,默认端口 443
- DNS 解析:域名(如www.baidu.com)通过 DNS 解析转换成服务器 IP 地址,浏览器才能发起连接。
- HTTP 与 HTTPS 核心区别
- HTTP:明文传输,数据无加密,存在窃听、篡改风险
- HTTPS:基于 TLS 加密传输,数据安全,防止窃取与篡改
- HTTP 两种请求方法 GET / POST
- GET:参数拼在 URL,明文可见,适合查询数据,有长度限制
- POST:参数放在请求体,隐藏传输,适合提交表单、上传数据,无硬性长度限制
- HTTP 响应状态码
- 1xx:信息类(接收请求,继续处理)
- 2xx:成功(200 OK 请求正常处理)
- 3xx:重定向(跳转新地址)
- 4xx:客户端错误(404 页面不存在、403 权限拒绝)
- 5xx:服务端错误(500 服务器内部异常)
二、浏览器与 TCP 服务器通信流程
- 浏览器调用
connect()发起 TCP 三次握手,和服务器(IP + 端口)建立 TCP 连接; - 浏览器发送HTTP 请求报文给服务器;
- 服务器解析请求,构造HTTP 响应报文返回浏览器;
- 两种 TCP 连接模式:
- 短连接:一次请求响应完成后,调用
close()直接断开 TCP 连接; - 长连接(HTTP1.1 默认):连接不断开,复用同一条 TCP 通道完成多次请求 - 响应交互,减少反复握手开销。
- 短连接:一次请求响应完成后,调用
- 底层依托 TCP 服务器承载上层 HTTP 协议,TCP 负责可靠数据传输,HTTP 规定数据格式。
三、前端网页基础三剑客
网页由三类文件配合渲染:
- HTML:页面骨架文档,搭建文字、图片、链接等基础结构
- CSS:页面布局美化,控制颜色、尺寸、排版样式
- JS:页面交互脚本,实现点击、动画、数据交互等动态功能
select 是 Linux 早期 IO 多路复用接口,靠位图 fd_set 管理待监控文件描述符,可单线程监控多个套接字。 它通过四个宏操作位图,函数能监控读、写、异常三类 IO 事件,支持设置阻塞超时。 调用时 fd 集合会被内核修改,需要备份集合循环复用;返回值区分事件就绪、超时、报错三种情况。 TCP 服务端用它同时监听新连接和客户端数据读写。 缺点是最多监控 1024 个 fd,每次调用要拷贝集合、内核遍历全部 fd,并发高性能差,只适合少量连接场景。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)