操作系统
Linux常用操作
架构
- 早期:lamp/lnmp架构(Linux, Apache/Nginx, MySQL, PHP/Python)
- 现在:微服务容器
常考linux命令
- 查命令
man <command>
=> 简化版man:tldr <command>
pip --help
- 文件目录操作命令
- chown/chmod/chgrp
- ls/rm/cd/cp/mv/touch/rename/ln(硬链接&软链接)
- locate/find/grep
- 文件查看
- 编译器 vi/nano
- 查看文件 cat/head/tail
- 交互式查看文件 more/less
- 进程操作
- ps 查看进程
- kill 杀死进程(加参数不同的信号。执行的原理?)
- top/htop 监控进程
- 内存操作工具
- free 查看内存
- 了解每一列的具体含义
- 排查内存泄露
- 网络操作
- ifconfig 网卡信息
- isof/netstat 端口信息
- ssh/scp 远程登录/复制
- tcpdump 抓包
- 用户/组操作
- useradd/usermod
- groupadd/groupmod
线程&进程
线程vs进程
- 进程:对运行时的程序的封装,系统资源调度和分配的基本单位
- 线程:进程的子任务,cpu调度和分配的基本单位,实现进程内并发
- 一个进程可以包含多个线程,线程依赖进程存在,并共享进程内存
线程同步的方式(保证线程安全)
- 互斥量(锁):同一时刻只有一个线程
- 信号量:控制同一时刻多个线程访问同一资源的线程数量
- 事件:通过通知的方式保持多线程同步
进程间通信(共享信息)
- 管道(pipe:有名/匿名)
- 信号(signal):e.g.
command + C
终止线程 - 消息队列(message)
- 共享内存
- 信号量(semaphore)
- 套接字(socket):web应用通常都是这种
多线程
threading.Thread
类创建线程start()
启动线程join()
等待线程结束
多进程
- multiprocessing 多进程模块
Multiprocessing.process
类实现多进程- 一般在cpu密集程序,避免gil影响(python有GIL,可以用多进程实现cpu密集程序)
内存管理
分页机制
- 逻辑地址和物理地址分离的内存分配管理方案
- 程序的逻辑地址划分为固定大小的页(页号)
- 物理地址分为同样大小的帧(块号)
- 通过页表来映射逻辑地址到物理地址
分段机制
- 满足代码的一些逻辑需求
- 数据共享,数据保护,动态链接
- 段表来实现逻辑地址和物理地址的映射关系
- 段内连续分配,段间离散分配
分页&分段
- 页:内存利用率的角度;大小固定,操作系统决定
- 段:用户角度,用于数据保护、数据隔离等用途;大小不固定,由用户程序决定
虚拟内存
- 局部性(时间、空间)原理:程序运行的时候必要的信息装入内存
- 内存中暂时不需要的内容放到硬盘上
- 系统似乎提供了比实际内存大的多的容量,称为虚拟内存
页面置换的三种方法
- OPT:未来最后使用的页置换掉
- FIFO:先进先出
- LRU:最久没使用的页面跳台
内存抖动
- 频繁的页调动行为,进程不断产生缺页中断
- 置换一个页,又不断再次需要这个页
- 运行进程太多;杀掉无关的进程 & 增加物理内存
python垃圾回收机制原理
- 引用计数为主(循环引用无法解决)
- 引用计数增加
- 对象创建 a = 1
- 对象被引用 b = a
- 对象作为参数传递 func(a)
- 对象存在容器中 i = [a]
- 引用计数减少
- 使用
del
的命令可以减少引用计数,但不一定会回收 - 引用指向了别的对象 b =none
- 离开的对象的作用域(函数执行结束)
- 从一个容器移除对象或销毁容器
- 使用
- 循环引用:两个对象互相引用
- 引用计数增加
- 引用标记清除、分代回收解决引用计数的问题
- 标记清除:从根对象开始不断访问可达点,不可达的就清除
- 分代回收:
- 时间换空间的技术
- 将对象分成0,1,2三代(用双向链表来表示)
- 对于每一代,如果对象数量达到了阈值,则执行标记回收
- 没有被清除的对象放入下一代
- 0代触发将清理所有三代,1代触发会清理1, 2代,2代触发后只会清理自己。