我要好offer之 系统基础大总结
1. APUE Unix环境高级编程
(1) Unix基础知识: 内核->系统调用->shell和库函数->应用软件
(2) 文件I/O:read函数返回值、进程的文件描述符表、文件共享、inode、fcntl函数
(3) 文件和目录:文件类型(普通、目录、socket、FIFO、PIPE)、文件系统(硬链接、软链接)
(5) 进程环境:进程终止情况、longjmp、volatile用法
(6) 进程控制:fork(返回值、父子进程的文件描述符表)、wait函数、exec系函数
(7) 信号:三种处理方式、常见信号(SIGCHLD、SIGSEGV)及其默认处理方式
(8) 线程同步:进程和线程的异同点、线程回调函数的传参、进程和线程原语对比、线程同步(读写、写写、i++多线程、mutex)
(9) 高级I/O(一):非阻塞I/O、select使用、readn和writen封装、mmap映射
(10) 高级I/O(二):管道、消息队列、共享存储器mmap
(11) 网络套接字:大小端字节序、addrinfo结构体、getaddrinfo函数、tcp_listen和tcp_connect封装
2. Linux系统编程
(1) 系统调用、API和ABI、文件(各种类型简介、inode、软链接、硬链接)、进程简介
(2) 文件I/O:read函数返回值、readn和writen函数封装、文件定位、文件同步、文件截断、多路I/O(select、poll)、Linux内核实现
(3) 标准I/O缓冲:测试最佳I/O缓冲区大小、三种类型缓冲、标准I/O的线程安全、标准I/O的缺点
(4) 高级I/O:聚集I/O(readv、writev性能好、原子性)、epoll(LT和ET)、mmap(优缺点)、I/O调度算法(电梯调度)
(5) 进程管理:进程pid分配方法、fork and exec、copy on write、wait、僵尸进程的回收
(6)进程调度:Linux进程调度算法(FIFO、最短优先、时间片轮转)、CPU绑定(缓存影响)
(7) 线程:虚拟化抽象(虚拟内存与进程关联、虚拟处理器与线程关联)、多线程好处、多线程i++解析、pthread使用、RAII封装mutex
(8) 文件和目录管理:文件inode节点元数据、目录操作、软链接和硬链接、块设备/dev/null
(9) 内存管理:进程地址空间、动态分配内存(malloc、calloc、brk)、数据对齐、匿名文件映射、变长数组
(10) 信号:信号的3中处理方式、常见的信号
(11) 时间:gettimeofday、sleep休眠、定时器alarm
3. 位、字节、整型
字节序问题:
大端:地址为 阅读顺序:Sun系统 和 网络字节序 小端:地址为 逆阅读序:X86

信息 = Bit位 + 解释方式,无论怎么转换,Bit位是永远不变的,只有解释方式改变了
对于int的使用,参见:Google c++编程规范中int型使用
C语言整型溢出问题by @左耳朵耗子
尽量不要使用无符号数,极易bug:当执行一个运算时,如果一个运算数是有符号的而另一个是无符号的,那么c语言会隐式地将有符号数强制类型转换为无符号数
比如:函数参数类型为size_t, 我传入实参-1,这时-1会隐式的 转换为 最大正数,完全错了
4. 数据对齐、结构体访问、offsetof
结构体数据对齐有2个原则:
(1) 每个成员数据的偏移 必须是 该数据类型大小的整数倍
(2) 整个结构体大小 必须是 最大数据类型大小的 整数倍
数据对齐产生了 内部碎片,为了使内部碎片最小,必须让 最大的数据类型摆放在最前面

如何计算 每个成员数据在结构体内的偏移呢? C语言提供 offsetof宏
#define offsetof(type, member) (size_t)&(((type*)0)->member)
struct test {
int val;
int a[];
};
// 结构体访问和数组访问的实质都是 首地址加上对应偏移,然后读取对应数据,注意 取地址 和 取成员 操作的区别
struct test* ptest = NULL; // 结构体首地址为0
fprintf(stdout, "1:%p\n", &ptest->val); // 注意:这是读取 结构体成员数据的偏移,直接就是 首地址加上 offset,而不是 先取到数据然后取地址
fprintf(stdout, "2:%d\n", ptest->val); // 错误,可以打印地址0的地址值,但是不能访问地址值为0的数据
fprintf(stdout, "3:%p\n", &ptest->a); // 正确,首地址加上offset
fprintf(stdout, "4:%p\n", ptest->a); // 同上,数组名退化为 数组首地址,所以这还是一个取地址操作
具体详见:C语言结构体内的数组和指针by@左耳朵耗子
5. cache 矩阵乘法
CPU Cache示例by@左耳朵耗子
C语言数组行优先存储,当数组大小超过 缓存块大小时,不同的存取方式之间 差别很大,以 A[N][N] * B[N][N] 存储在 C[N][N]中




6. 编译链接

静态编译和动态编译
详见陈硕的 <C++编译链接模型精要>

链接器主要完成两件事:
(1) 符号解析:将每个符号的引用(reference)对应到相应符号的定义(definition)
C程序员应该尽可能使用static属性在模块内部隐藏变量和函数声明,即模块私有

注:使用 readelf命令来查看目标文件的符号表
当linker遇到重名时:
重名Local定义:编译器解决
重名Global定义:强符号(函数名和已初始化的全局变量)和弱符号(未初始化的全局变量)

(2) 重定位:合并不同文件时修改符号地址,将符号的相对地址 改为 绝对地址


Linux系统为动态链接库提供了一个简单的接口,允许应用程序在运行时加载和链接共享库
#include <dlfcn.h>
void* dlopen(const char* filename, int flag); // dlopen函数加载和链接共享库filename
void* dlsym(void* handle, char* symbol); // dlsym函数的输入参数为dlopen打开的共享库句柄和符号名,返回符号的地址
int dlclose(void* handle);
7. 进程间通信
(1) 管道、FIFO(命名管道)
管道:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系
FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
(2) 信号(Signal)
信号用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)
(3) 报文(Message)队列(消息队列)
消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
(4) 信号量(semaphore)
主要作为进程间以及同一进程不同线程之间的同步手段,是一个计数器,用于多进程对共享数据对象的访问
(5) 共享内存
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问
共享内存是最快的 IPC 方式(因为数据不需要在客户进程和服务器进程之间复制)
使用mmap进行文件内存映射 和 匿名存储映射(将fd设为-1)
(6) socket套接字
套接字接口既可以用于多机之间进程通信,也可以用于单机内部进程通信
8. 进程同步原语
(1) 互斥锁
(2) 条件变量
(3) 读写锁
9.高效拷贝文件


10.高效传输远程文件


我要好offer之 系统基础大总结的更多相关文章
- 我要好offer之 概率题大总结
1. 利用等概率Rand5生成等概率Rand3 Rand5生成等概率Rand3 这个题目可以扩展为:利用等概率RandM生成等概率RandN (M > N) 这里,我们首先明白一个简单的知识点: ...
- 我要好offer之 排序算法大总结
1. 插入排序 (1) 直接插入排序 void StraightInsertionSort(std::vector<int>& num) { || num.size() == ) ...
- 我要好offer之 字符串相关大总结
1. str*系列手写代码 a. 一定要注意末尾'\0'的处理,切记切记 b. 一定要对输入做有效性判断,多用断言就是了 int Strlen(const char* str) { assert(st ...
- Linux实战教学笔记06:Linux系统基础优化
第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...
- 12、ERP设计之 系统基础管理(BS)- 模块与菜单的关联
ShareERP2013-10-03 模块:具有功能设计.权限绑定,链接用户菜单与系统的重要桥梁. 菜单:是用于显示与用户交互的重要入口,更是导航系统的舵手,所以它的设计直接影响到用户体验. 菜单可能 ...
- django模板系统基础
模板系统基础Django模板是一个string文本,它用来分离一个文档的展现和数据 模板定义了placeholder和表示多种逻辑的tags来规定文档如何展现 通常模板用来输出HTML,但是Djang ...
- Windows7系统基础操作
Windows7系统基础操作 操作系统是人机交互的时候桥梁,一种计算机软件,软件分为:系统软件+应用软件 区别是:系统软件是可以直接安装在硬件上的计算机由硬件和软件两部分组成 操作电脑核心是操作电脑的 ...
- Linu之linux系统基础优化和基本命令
Linux系统基础优化和基本命令 网络参数设定命令 ifconfig: 查询,设置网卡和ip等参数 ifup,ifdown: 脚本命令,更简单的方式 ip: 符合指令,直接修改上述功能 编辑网卡配置文 ...
- ERP设计之系统基础管理(BS)-日志模块设计(转载)
原文地址:8.ERP设计之系统基础管理(BS)-日志模块设计作者:ShareERP 日志模块基本要素包括: 用户会话.登录.注销.模块加载/卸载.数据操作(增/删/改/审/弃/关等等).数据恢复.日志 ...
随机推荐
- JavaScript -- 条件语句和循环语句
if语句 在我们开发程序的时候,经常会遇到选择题,例如,年龄大于18,你就可以抽烟喝酒烫头,年龄小于18,你就只能吃饭喝水.在我们的代码中,我们可以用if语句来实现这种判断 语法一: if( cond ...
- perl -p -i -w -e
.txt kllk nciuwbufcbew``````//.]];s[[..; klklkl x,dsncdk,;l,ex xw,eocxmcmck .txt .txt kkkkkkkkkkkkkk ...
- PayPal为什么从Java迁移到Node.js 性能提高一倍 文件代码减少44%
大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 Node.js at PayPal 解释了为什么从Java迁移出来的原因: 开发效率提高一倍(2 ...
- 学习笔记(二):使用 TensorFlow 的起始步骤(First Steps with TensorFlow)
目录 1.工具包 TensorFlow 张量 (Tensor) 图 (graph) TensorBoard 2.tf.estimator API Estimator 预创建的 Estimator (p ...
- php生成zip压缩文件的方法,支持文件和压缩包路径查找
/* * new creatZip($_dir,$_zipName); *@ _dir是被压缩的文件夹名称,可使用路径,例 'a'或者'a/test.txt'或者'test.txt' *@ _zipN ...
- Django之URL
URL是用户请求路径与views视图处理函数的一个映射 简单的路由配置及实现 这里是pycharm编辑开发为例,新建的django项目,会在url.py下自动生成这样一段代码: from django ...
- Java装饰者模式(Decorator)
一.定义 装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余).装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展.装饰 ...
- PAT Basic 1073
1073 多选题常见计分法 批改多选题是比较麻烦的事情,有很多不同的计分方法.有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 50% 分数:如果考生选择了任何一 ...
- Monkey与MonkeyRunner之间的区别
为了支持黑盒自动化测试的场景,Android SDK提供了monkey和monkeyrunner两个测试工具,这两个测试工具除了名字类似外,还都可以向待测应用发送按键等消息,往往容易产生混淆,以下是他 ...
- UVa 465 Overflow——WA
上次那个大数开方的高精度的题,UVa113 Power of Cryptography,直接两个double变量,然后pow(x, 1 / n)就A过去了. 怎么感觉UVa上高精度的题测试数据不给力啊 ...