linux奇怪问题整理

来源:互联网 发布:socket网络通信流程 编辑:程序博客网 时间:2024/05/16 04:46

1,寻路算法

http://qiao.github.io/PathFinding.js/visual/




5,linux系统奇怪问题

5.1 命令行输入

linux中输入命令超过一行时按home键回不到上一行。可能和shell的缓存有关系,是否需要执行命令sync一下。

5.2 如何生成内存快照?

fork+Woc

调用fork,现在有了子进程和父进程;父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数据是fork时刻整个数据库的一个快照;写完时子进程退出。

5.3 如何判断内存泄露?

当出现了内存泄漏后,测试人员可以长时间运行程序,看内存占用情况,如果程序运行很长时间后,内存使用率不断增大,这时可以考虑是否是内存泄漏了。我们可以使用第3方工具检查。

5.4 磁头如何定位磁道扇区?



5.5 malloc如何分配空间?

在内存1G的32位电脑上malloc(2G)空间   会发生什么?
这个跟1G的硬件没关系的,主要是你进程当前的空间还有没有2G的连续空间
只有你真正去写某个地址的时候,才会真正分配内存


3.8,Linux下什么叫做安装?

一般步骤:

./configure 主要用脚本来配置系统环境

make 主要用来编译源码为可执行文件

make all 编译所有,将内容设置到默认的文件夹中去

PS:如何实现一个最简单的软件(安装,卸载)

3.9,为什么默认编译输出是a.out?

a.out是旧版类Unix系统中用于执行档、目的码和后来系统中的函数库的一种文件格式,这个名称的意思是ssembler output(即汇编输出)。尽管目前大多数类Unix系统都已改用ELF格式,不再采用a.out格式,但编译器和链接器依然会在用户未指定文件名时,将输出文件取名为“a.out”。




4,linux函数使用

4.1,strcpy和strcat

strcpy:

原型声明:extern char *strcpy(char* dest, const char *src);头文件:#include <string.h>功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回:指向dest的指针。
strcat:

原型:extern char *strcat(char *dest,char *src);用法:#include <string.h>在C++中,则存在于<cstring>头文件中。功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回:指向dest的指针。
所以不用考虑最后的/0,一般使用方法,直接strcpy,再strcat。

strcpy(string,var);strcat(string,"=");strcat(string,value);

4.2,gmtime函数返回结构指针的问题

问题描述:

在Linux下gmtime和localtime函数都能对用time函数获取的时间分解成一个tm结构,它们的原型为:

struct tm* gmtime(const time_t *timeval);struct tm* localtime(const time_t *timeval);
它们都会根据一个time_t的指针返回一个tm结构变量的指针,然而,我却不知道这个指针所指向的变量实际是储存在哪里的,这个函数是怎么为这个变量分配内存的,而且使用完这两个函数,还不能使用free来释放内存,使用free会产生内存错误。

结论:

是静态变量,gmtime和localtime共用一个静态变量用于返回值,每次调用都会改写这个值。返回值指向一个静态分配的结构,该结构可能会被接下来的任何日期和时间函数调用覆盖。

4.3,malloc和free

malloc返回一个指针,free传入该指针,系统如何知道free多大空间?

4.4,设计一个函数,是否需要size_t namelen?

比如P133

int gethostname(char*name ,size_t namelen)



3.1,阻塞vs非阻塞vs同步vs异步

3.1.1 阻塞vs非阻塞

层次:对于一个调用的返回状态
标准:是否会挂起当前进程/线程
场景:
阻塞:一个进程/线程内,当进程调用一个阻塞的系统函数(比如write)时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep 指定的睡眠时间到了)它才有可能继续运行。注意不包括因为时间片原因系统挂起当前进程。
非阻塞:函数立刻返回结果,以read为例,如果设备暂时没有数据可读就返回-1,同时置errno为EWOULDBLOCK(或者EAGAIN,这两个宏定义的值相同),表示本来应该阻塞在这里。以write来举例,可以设置write为非阻塞的。比如要写1K,但是缓存只有0.5K,于是需要等待(阻塞),但是这里设置为非阻塞的,于是就立刻返回已经写了0.5K,剩余的写要自己再次处理。注意,阻塞非阻塞和时间长短其实没有关系(非阻塞的“立刻返回”不是指时间)!而主要是指如I/O设备的等待

在I/O中,其实阻塞方式会好一点,非阻塞I/O有一个缺点,如果所有设备都一直没有数据到达,调用者需要反复查询做无用功,如果阻塞在那里,操作系统可以调度别的进程执行,就不会做无用功了。

3.1.2 同步vs异步

层次:针对一个调用(函数)或多个调用之间的关系
标准:是否完成在同一个栈层上
场景:
f(){
f1();
f2();
}
同步:对于一个函数调用f(),如果内部又调用了很多其他f1();f2();,但是最终返回到的还是f()栈上,那么对f()调用来说,是同步的。
异步:对于多个函数调用f1();f2();调用完了f1(),再调用f2(),前者的栈做完就推掉了,那么对于f1()和f2()的顺序执行来说,是异步的。

3.1.3 顺序执行

上述的异步某种程度上是一种顺序执行。

3.1,阻塞vs非阻塞vs同步vs异步

3.1.1 阻塞vs非阻塞

层次:对于一个调用的返回状态
标准:是否会挂起当前进程/线程
场景:
阻塞:一个进程/线程内,当进程调用一个阻塞的系统函数(比如write)时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep 指定的睡眠时间到了)它才有可能继续运行。注意不包括因为时间片原因系统挂起当前进程。
非阻塞:函数立刻返回结果,以read为例,如果设备暂时没有数据可读就返回-1,同时置errno为EWOULDBLOCK(或者EAGAIN,这两个宏定义的值相同),表示本来应该阻塞在这里。以write来举例,可以设置write为非阻塞的。比如要写1K,但是缓存只有0.5K,于是需要等待(阻塞),但是这里设置为非阻塞的,于是就立刻返回已经写了0.5K,剩余的写要自己再次处理。注意,阻塞非阻塞和时间长短其实没有关系(非阻塞的“立刻返回”不是指时间)!而主要是指如I/O设备的等待

在I/O中,其实阻塞方式会好一点,非阻塞I/O有一个缺点,如果所有设备都一直没有数据到达,调用者需要反复查询做无用功,如果阻塞在那里,操作系统可以调度别的进程执行,就不会做无用功了。

3.1.2 同步vs异步

层次:针对一个调用(函数)或多个调用之间的关系
标准:是否完成在同一个栈层上
场景:
f(){
f1();
f2();
}
同步:对于一个函数调用f(),如果内部又调用了很多其他f1();f2();,但是最终返回到的还是f()栈上,那么对f()调用来说,是同步的。
异步:对于多个函数调用f1();f2();调用完了f1(),再调用f2(),前者的栈做完就推掉了,那么对于f1()和f2()的顺序执行来说,是异步的。

3.1.3 顺序执行

上述的异步某种程度上是一种顺序执行。


3.2,回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

3.3,内核态和用户态的区别是什么

场景:Linux在启动时,会有0号进程->1号内核进程->1号用户进程(init进程)的区别。之前只了解内核态和用户态的概念,那么实际上这两者最本质区别是什么?(最近研究问题发现很关注本质,哪些是因,哪些是果,哪些是本质,哪些是表现)
回答
内核态和用户态最本质的区别:应该是执行哪一部分代码,如果执行的是linux kernel代码,那么称为内核态,如果是用户代码,那么是用户态。或者再严格一点,是CPU的特权级的不同。
内核态和用户态的外在表现:主要是内核态权限较高,可以进行对硬件操作,分物理内存等。而用户态则不可以。
内核态和用户态是在什么时候切换的:当有系统调用或中断时,会进入SYSCALL,这时开始运行内核代码,老版本linux中唯一方式是通过中断int $0x80(语见《深入理解LINUX内核P400》),运行权限的区别在于这时CPU的特权级别的切换。在运行完毕后再有SYSEXIT进行退出。

举个栗子:比如对于一段程序:
void  f(){fork();}

这段程序在fork 之后,最本质实际上调用了sys_fork()函数,即开始运行内核代码(内核代码是通过中断进入的,所以运行级别在硬件上[CPU]设置了),CPU可以开始执行特权指令,使用系统资源。使用完后又返回到用户代码,这时就是又回到了用户态。

处理器总处于以下状态中的一种:
1、内核态,运行于进程上下文,内核代表进程运行于内核空间;
2、内核态,运行于中断上下文,内核代表硬件运行于内核空间;
3、用户态,运行于用户空间。




3.10 端口有限是否意味着应用有限?

服务器:一般80就提供HTTP访问使用,所以服务器使用知名端口,开启少许服务进程。

客户端:一般使用非知名端口,而是随机分配的,所以一个客户端进程可以开启不超过65535个进程,也即是有限的。

3.11 文本文件(ASCII)和二进制文件的区别?

xx


3.10 端口有限是否意味着应用有限?

服务器:一般80就提供HTTP访问使用,所以服务器使用知名端口,开启少许服务进程。

客户端:一般使用非知名端口,而是随机分配的,所以一个客户端进程可以开启不超过65535个进程,也即是有限的。

3.11 文本文件(ASCII)和二进制文件的区别?

xx

1 0