我要好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 日志模块基本要素包括: 用户会话.登录.注销.模块加载/卸载.数据操作(增/删/改/审/弃/关等等).数据恢复.日志 ...
随机推荐
- echarts实现仪表盘(自己动起来,没有后端,顺便重温math.random
let a = parseInt(Math.random() * (2 + 1), 10); let arr = []; arr.push(res[a]); let option = { toolti ...
- 简易数据分析 02 | Web Scraper 的下载与安装
这是简易数据分析系列的第 2 篇文章. 上篇说了数据分析在生活中的重要性,从这篇开始,我们就要进入分析的实战内容了.数据分析数据分析,没有数据怎么分析?所以我们首先要学会采集数据. 我调研了很多采集数 ...
- tomcat - 自带日志的区分
在tomcat 中,logs文件夹下会存放着一些tomcat自带的日志文件,其中有三种文件: 1 > localhost_access_log.2017-12-28 文件,它用来记录tomcat ...
- java基础—数组
一.数组的基本概念 数组可以看成是多个相同类型数据组合,对这些数据的统一管理. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量. 数组的元素可以是任何数据类型,包括基 ...
- VueX源码分析(4)
VueX源码分析(4) /module store.js /module/module.js import { forEachValue } from '../util' // Base data s ...
- NOIP模拟赛 抓牛
[题目描述] 农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来. 他们都站在数轴上.约翰在N(O≤N≤100000)处,奶牛在K(O≤K≤100000)处.约翰有两种办法 ...
- 10GNU C语言函数调用
6. C 函数调用机制概述 在 Linux 内核程序 boot/head.s 执行完基本初始化操作之后,就会跳转区执行 init/main.c 程序.那么 head.s 程序时如何把执行控制转交给 ...
- nginx的url重写
1.1 简介 url重写由ngx_http_rewrite_module模块提供,默认会安装,但该模块功能的实现需要pcre.URL重写技术不仅要求掌握几个指令的语法.熟悉简单的正则表达式,还需要尽量 ...
- 如何在 CentOS 7 上安装 Python 3
当前最新的 CentOS 7.5 默认安装的是 Python 2.7.5,并且默认的官方 yum 源中不提供 Python 3 的安装包.这里主要介绍两种在 CentOS 7 中安装 Python 3 ...
- cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
参考 http://blog.csdn.net/mazicwong/article/details/54946952 1.到https://curl.haxx.se/ca/cacert.pem复制下 ...