0%

COW技术初窥

Linux写时拷贝技术(copy-on-write):COW 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢?

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。

当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

在网上看到还有个细节问题就是,fork之后内核会通过将子进程放在队列的前面,以让子进程先执行,以免父进程执行导致写时复制,而后子进程执行exec系统调用,因无意义的复制而造成效率的下降。

访问限定符说明

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. class的默认访问权限为private,struct为public(因为struct要兼容C) 注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

C++的class与C的struct的区别:C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用来定义类。和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式是private

auto关键字

C语言中其实就有auto关键字,修饰可变化的量,但是由于平时我们直接使用int a = 10;也是声明变量,编译器已经自动帮我们加上了auto关键字,是C语言中应用最广泛的一种类型,也就是说,省去类型说明符auto的都是自动变量! 随着时代进步,Java10中有一个新特性,就是使用var来定义变量,当然前提是类型可推导,语言总是在演化,C++11也是支持了这个新特性,不过在C++11中是auto关键字:使用auto的时候,编译器根据上下文情况,确定auto变量的真正类型! 接下来演示一下auto的使用:

int main() {
	auto a = 10;
	auto b = 20;

	list<string> s;

	list<string>::iterator be = s.begin();
	list<string>::iterator en = s.end();

	auto be2 = s.begin(); //很显然使用auto可以减少很多不必要的代码
	auto en2 = s.end();

	return 0;
}

很显然使用auto可以减少很多不必要的代码,但是:

  • auto不能作为函数参数
  • auto不能直接用来声明数组
  • auto不能定义类的非静态成员变量
  • 实例化模板时不能使用auto作为模板参数
  • auto作为函数返回值时,只能用于定义函数,不能用于声明函数
  • 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法

在windows平台和Linux平台下都大量存在着库,库的本质还是一个文件,这个文件里面就是程序员编写的经过编译,汇编后的功能代码,写成库的方式可以实现代码保密,以及分发和部署方便。通常分为静态链接库和动态链接库,下面来看看两者的概念和区别。

六大设计原则

既然说到设计模式那就顺便回顾一下六大设计原则,六大设计原则是心法,二十三种设计模式是内功,下面只是简明的叙述了一下,后面还会有更详细的说明! 一 、 类单一职责原则:Single Responsibility Principle (SRP) 一个类只有一个引起这个类变化的原因。即一个类只完成一个功能,如果做不到一个类只完成一个功能,最少要保证一个方法只完成一个功能。

二、依赖倒置原则:Dependency Inversion Principle (DIP) 高层组件应该依赖抽象而不依赖具体,即面向接口编程,一般依赖的成员变量或者参数都应该是抽象的不应该是具体的。

三、里氏替换原则:Liskov Substitution Principle (LSP) 凡是父类出现的地方都可以用子类代替并且原功能没有发生变化,子类不应该覆盖父类的非抽象方法。

四、迪米特法则:Least Knowledge Principle (LKP) 一个类要尽量的封装自己,一个对象应该对其他对象有最少的了解,一个类只需要知道自己需要耦合或者调用类的public方法即可。

五、接口隔离原则:Interface Segregation Principle (ISP) 一个接口完成的功能尽可能的单一,不要让一个接口承担过多的责任。

六、开闭原则:The Open-Closed Principle (OCP) 对扩展开放,对修改闭合。

一、fopen函数

#include <stdio.h>
FILE *fopen(const char *path, const char *mode);

参数说明: path:要打开的文件路径+文件名 mode:打开模式,下面是第二个参数的说明 来自CentOS 7:man 3 fopen

函数重载

方法重载 (overload) C++允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载(Function Overloading),借助重载,一个函数名可以有多种用途。

永远记住一点:函数重载只与参数列表有关,与返回值类型无关