杂记小结

1.1管道的大小有默认值65536个字节,即是2的16次方,而与tcp相比较,都是字节流,管道的大小可以通过fcntl函数来修改。全双工的管道socketpair

1.2并行性:两个及多个事件同一时刻发生
     并发性:两个或多个事件在同一时间间隔内发生 
     对象:是指现实世界中具有相同属性,服从相同规则的一系列事务的抽象

2.提高服务器的性能
     1.分布式,何为分布式: 多台服务器,多台数据库服务器,组成的模型,客户进行访问。集群:集群的机器具有相同的功能,完成相同的事件
     2.多线程,多进程编程
     3.数据库连接池

3.nginx多进程模型
    1> nginx 在启动后,会有一个 master 进程和多个 worker 进程。master 进程主要用来管理 worker进程,其功能包含:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker进程退出后 (异常情况下),会自动重新启动新的 worker 进程
     2>worker 进程的个数是可以设置的,一般会设置与机器 cpu 核数一致, nginx 为了更好的利用多核特性,提供了cpu 亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来 cache 的失效
     3>首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket 之后,然后再 fork 出多个 worker 进程,这样每个 worker 进程都可以去 accept 这个 socket(当然不是同一个 socket,只是每个进程的这个 socket 会监控在同一个 ip 地址与端口,这个在网络协议里面是允许的)。 一般来说,当一个连接进来后,所有在 accept 在这个 socket 上面的进程,都会收到通知,而只有一个进程可以accept 这个连接,其它的则 accept 失败,这是所谓的惊群现象。 nginx提供了一个 accept_mutex ,这是一个加在 accept 上的一把共享锁
     4>对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查上时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断, master 进程则很快重新启动新的 worker 进程
     5>nginx 使用一个叫 ngx_accept_disabled 的变量来控制是否去竞争 accept_mutex 锁。不仅处理了惊群现象,还考虑到负载均衡,将任务均匀的分配到每个进程中
    注意:现在的Linux系统在底层已经解决了惊群现象

4.数据库分布式问题:(分布式数据库服务器,分布式服务器 )
  1>单个表数据量太大  2> 单个库数据量太大  3>单台数据量服务器压力很大  4>读写速度遇到瓶颈
   负载均衡,读写分离,分库分表----分布式事务,保证数据的一致性

5>提问:
1>判断两个单向链表是否相交,如果相交,求出交点。     
2>在一个有环链表中,如何找出链表的入环点。如何检测一个链表中有环
3>如何寻找到链表中环的入口点
4>交叉链表的第一个公共结点,Y型的,如果是X型的
Y型结构:
     1.遍历两个队列,使用栈将其压入,完毕之后,从栈顶出结点,如果两个结点不相同的话,则上次出栈的结点为公共结点
     2.得到两个链表的长度,然后用长的减去短的为x,让指针在长的上面先走x步,然后从头遍历当第一个相同结点就是其第一个公共结点
5>链表中倒数第K个结点
6>二叉树的最近公共父节点
     1.如果是排序的二叉树,从根开始遍历,找到第一个比大的小,比小的大的结点
     2.不是排序二叉树,是否有指向父节点的指针,
     3.不是排序树也没有父节点
7>求最大公约数  1普通方法  2辗转相除法(欧几里得)3更相减损术(九章算术)4更相减损术和移位运算  5找出缺损的数

6.智能指针的作用,智能指针的引用计数,智能指针的交叉引用问题及解决。
7.vector底层的迭代器失效问题的解决
8.shared_ptr引用计数智能指针
   线程安全问题,进程中的资源在线程中可见,几个线程都可以访问操作。智能指针和STL容器都不是线程安全的。
强引用,弱引用

linux内核源代码情景分析
1.页面映射分为两级和三级的,在第一层的页面中所存储的是第二层页面的地址,在线性地址中有其下标,那么这个指向页面的地址是否还要经过地址翻译才能得到其物理地址还是直接就是物理地址???
2.内存扩展成8M是要进行地址扩展成三层?
3.在地址映射成虚拟地址过程中,是否地址总线的大小对整个翻译工作影响巨大?
4.了解内存条进行内存扩展的底层寻址变化?
5.扩展成8M,那么地址总线就是33根,是物理上已经实现了36根,然后根据用户的添加进行选择合适的地址总线数,那么又是怎么进行物理寻址的?
6.windows的内存映射与Liunx是否一样,是否只是取决于CPU的设计??
7.CR3中所存储的是从mm_struct中得到的数据,其在内核中存储
8.经过该段映射拿到了段首地址,然后进而组成了线性地址,为何说这个过程是无用的?
9.用户的程序可以由用户自己进行编写,而系统的是有系统设计者编写,系统设计者不会做不安全的事情,所以对自己的操作给予最高权限。在段映射过程中有许多的权限安全问题的检查首先拿到一个虚拟地址,得到段寄存器,进行段地址映射,而因为进程的虚拟地址的基址是0,导致了虚拟地址映射完毕之后和线性地址的值是移植的,该过程的进行主要是为了附和Intel CPU的设计
10.内核中的虚拟地址转化物理地址表示这个页表项在内核中??进程的创建中找结果

1.Liunx下一切皆文件,一个socket,使用create_epoll都会创建一个inode结点来进行文件管理?

2.poll进行添加回调函数,然后等待,如果有事件发生就添加队列,这个添加的过程如何做到?

3.一个poll可以监听多个文件描述符,一个文件描述符可以被多个进程所监听,这两者关系如何处理?等待队列中的元素是谁,是一个进程在等待多个文件描述符还是一个文件描述符被多个进程所等待,涉及到等待队列中的元素是谁?

4.一个poll调用完成后然后返回,返回之时在内核中建立的结构体和对文件添加的回调函数都要置空,然后下一次调用的时候重新建立添加?

5.发生了事件之后,什么时候返回,是事件累计到一定数量,还是超时时间到了,还是对整个文件描述符遍历一遍了就返回?

6.poll
  1>每次传入数组,然后建立结构体,复制用户空间的数据到内核之中
  2>每次都要对所有文件描述符进行事件的注册
  3>每次返回来之后进行遍历找到发生事件的文件描述符
       poll中除去了select中开辟了6个位数组用来记录所要监视的实践类型和发生事件的事件类型,而poll中使用了两个结构体,一个event通过位操作表示监视事件类型,revent表示发生事件的事件类型,封装在struct poll中

进行了初始化之后,然后拷贝用户的struct pollfd到内核中,调用do_poll将struct pollfd和回调函数传入,然后开始对每一页中的每一个文件描述符进行检测,是否发生事件,如果发生事件,调用wait函数改变revent和count值,然后返回查看count是否为0,是否超时,是否有信号,如果发生这些事情中的一个就跳出大循化,返回给用户。没有发生就将进行睡眠,一段时间后进行再次检测。

2017/7/3

线程间的通信目的主要是用于线程同步。所以线程没有像进程通信中的用于数据交换的通信机制。

如何在Linux下来查看可执行文件的汇编代码,ELF文件格式等Linux命令

处理线程安全,提供写时复制,确保协议,并且提供远程交互服务
std::auto_ptr。它是为解决资源所有权问题设计的,但是缺少对引用数和数组的支持。std::auto_ptr在被复制的时候会传输所有权。
在Boost中的智能指针有:
scoped_ptr,用于处理单个对象的唯一所有权;与std::auto_ptr不同的是,scoped_ptr可以被复制。
scoped_array,与scoped_ptr类似,但是用来处理数组的
shared_ptr,允许共享对象所有权
shared_array,允许共享数组所有权

可重入函数,一个函数被重入,表示这个函数还没有执行完成,由于外界因素或者内部调用,有一次进入该函数执行
可重入两种情况:1>多个线程同时执行2>函数自身调用自身

内核线程与用户线程
1.内核线程直接接受操作系统的调度
2.多对一模型,线程之间的切换由用户态的代码来进行,因此对于一对一模型,多对一模型的线程切换快速。如果有一个用户线程阻塞了,那么所有线程都无法执行,因为此时内核里的线程也随之阻塞。多对一的模型好处,高效的上下文切换和几乎无限制的线程数量
3.多对多线程,一个用户线程的阻塞不会引起所有用户线程的阻塞,对用户线程的数量也没有限制

通过file filename查看文件的格式信息
可执行文件和.o文件的区别  objdump进行查看elf文件格式文件
1.可执行文件有入口函数,.o的入口函数为全0
2..o文件经过编译没有经过链接过程,所以其中使用外部库的代码没有载入
3.可执行文件和.o文件都是相同的文件格式elf,使用objdump来查看编译过的文件或者可执行文件
4.编译过的文件中local符号都已经替换了,只有global符号没有进行处理,在写程序的时候有几个变量的符号的作用域已经确定,static修饰的符号是local

页面置换算法:最佳置换算法,先进先出置换算法,最近最久未使用算法
实现先进先出算法  队列queue
实现LRU最近最久未使用算法进行页面置换
    需要的一个特殊栈,可以进行头删,尾插,查找,删除第n个元素

处理机调度算法
短程调度:选择合适的进程使用cpu
     轮转调度算法
     优先级调度算法<抢占和非抢占>
     多队列调度算法
     多级反馈队列调度算法
中程调度:磁盘文件调入内存执行,内存文件调入交换分区

tr->TSS中存储的是什么?SAVEALL TSS thread_info
一个cpu一个tss
何时进行进程切换
硬件上下文  堆栈指针
switch_to宏
schedule调度函数


堆排序
死锁原因,场景,解决
红黑树
二分查找 递归非递归 
与面试官讨论如何处理错误输入或者其它错误
单例模式、简单工厂模式、工厂模式、抽象工厂模式
机智的我不管哪家公司问都是说从即日起到大四毕业,中间出了期末考试和毕业设计,都能参与实习,近期就能参加实习

linux命令

free查看内存的状态
mount挂载文件系统 umount卸载

bunzip2解压    bzip2压缩
gunzip解压   gzip压缩
zip unzip
split 切割文件 -b字节数
zgrep

nohup  ps kill  top《显示管理执行中的程序》
who
ipconfig

 文件,软链接,硬链接

:预先编译好的函数的集合
     静态库/共享库

编译程序:
     g++/gcc的区别:1>g++能编译.c和.cpp文件,gcc要手工加入所用到的库文件才能编译.cpp文件 
                                      2>底层符号处理不同
                                      3>g++不论是.c还是.cpp均以.cpp文件去处理,而gcc发现是.c就按照c语法处理,而g++发现是.cpp就按照c++语法去处理
                                        nm 查看elf文件中生成的符号
     makefile文件:管理工程

/*g++的底层和gcc底层符号的产生不同,若用gcc编译,加入g++的库,如果找不到这个库怎么办*/
g++对.c程序和.cpp程序都当作是cpp程序来处理,生成的符号都是C++式的。而gcc对.c程序当作c程序,.cpp程序当作C++程序来处理。gcc不能直接链接到g++库上,所以需要g++来进行链接或者指定链接库。

gcc不会定义__cplusplus宏,而g++会 。实际上,这个宏只是标志着编译器将会把代码按C还是C++语法来解释,如上所述,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则,就是已定义。 

调试程序:
     gdb:多线程调试
     strace:
     ltrace:
     valgrind: 查看是否有内存泄漏
     core文件: ulimit -c  gdb  file

进程与线程:
     僵死进程
     进程与线程的区别
     并发 同步 竟态条件  临界资源  临界区

进程间的同步:信号量(p,v操作)
线程间的同步:信号量,互斥量,条件变量
     
进程间的通信:管道,信号量,消息队列,套接字,信号
    有名管道,管道文件在磁盘中存储,但是管道文件的数据在内存中存储  ll查看文件的大小
    有名/无名管道:半双工,内存中存储,亲缘关系间通信还是任意进程间的通信

关闭linux防火墙:iptable -F   setenforce 0

你可能感兴趣的:(Linux编程)