1.基于连接与无连接
2.对系统资源的要求(TCP较多,UDP少)
3.UDP程序结构较简单
4.流模式与数据报模式
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
1.因为UDP可以是一对一,多对一,一对多,或者多对多的通信,所以每次调用sendto()/recvfrom()时都必须指定目标IP和端口号。通过调用connect()建立一个端到端的连接,就可以和TCP一样使用send()/recv()传递数据,而不需要每次都指定目标IP和端口号。但是它和TCP不同的是它没有三次握手的过程。
2.还可以通过在已建立连接的UDP套接字上,再次调用connect()实现以下功能:
a.指定新的IP地址和端口号。
b.断开连接。
这也与TCP有所不同,TCP套接字只能调用一次connect()函数。
浏览器向DNS服务器查找输入URL对应的IP地址。
本地的机器上在配置网络时都会填写DNS,这样本机就会把这个url发给这个配置的DNS服务器,如果能够找到相应的url则返回其ip,否则该DNS将继续将该解析请求发送给上级DNS,整个DNS可以看做是一个树状结构,该请求将一直发送到根直到得到结果。现在已经拥有了目标ip和端口号,这样我们就可以打开socket连接了。
DNS服务器返回网站的IP地址。
浏览器获取请求页面的html代码。
连接成功建立后,开始向web服务器发送请求,这个请求一般是GET或POST命令(POST用于FORM参数的传递)。GET命令的格式为: GET 路径/文件名 HTTP/1.0
web服务器收到这个请求,进行处理。从它的文档空间中搜索子目录mydir的文件index.html。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。
浏览器在显示窗口内渲染HTML。
最通常的方法最有效的是加定时器;也可以采用非阻塞模式。
设置非阻塞,返回之后用select检测状态)
某个套接字集合中没有准备好,可能会select内存用FD_CLR清该位为0;
网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等。
流无边界,数据报有边界.TCP是先进先出的,并且可靠.
1.面向链接:TCP面向链接,面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须通过三次握手先建立一个TCP连接。在一个TCP中仅有两方彼此通信,多播和广播不能用于TCP。UDP是不可靠的传输,传输前不需要建立链接,可以应用多播和广播实现一对多的通信。
2.可靠性:TCP提供端到端的流量控制,对收到的数据进行确认,采用超时重发,对失序的数据进行重新排序等机制保证数据通信的可靠性。而UDP是一种不可靠的服务,接收方可能不能收到发送方的数据报。
3.TCP是一种流模式的协议,UDP是一种数据报模式的协议。进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。TCP应用程序产生的全体数据与真正发送的单个IP数据报可能没有什么联系。TCP会有粘包和半包的现象。
4.效率上:速度上,一般TCP速度慢,传输过程中需要对数据进行确认,超时重发,还要对数据进行排序。UDP没有这些机制所以速度快。数据比例,TCP头至少20个字节,UDP头8个字节,相对效率高。组装效率上:TCP头至少20个字节,UDP头8个字节,系统组装上TCP相对慢。
5.用途上:用于TCP可靠性,http,ftp使用。而由于UDP速度快,视频,在线游戏多用UDP,保证实时性
僵尸进程:就是已经结束了的进程,但是没有从进程表中删除。太多了会导致进程表里面条目满了,进而导致系统崩溃,倒是不占用其他系统资源。
用top命令来查看服务器当前是否有僵尸进程
Tasks: 123 total, 1 running, 122 sleeping, 0 stopped, 0 zombie
zombie前面的数量就是僵尸进程到数量;
ps -efl
出现:
1 Z root 7325 7306 0 75 0 - 0 exit Mar19 ? 00:00:00 [Xsession]
最后有defunct的标记,就表明是僵尸进程。
首先用实参替换形参,将实参代入宏文本中;
然后如果实参也是宏,则展开实参;
最后再继续处理宏替换后的宏文本,若宏文本也包含宏则继续展开,否则完成展开。
具体来说包括两个概念.
1指针意味着已经有一个指针变量存在,他的值是一个地址,指针变量本身也存放在一个长度为四个字节的地址当中,而地址概念本身并不代表有任何变量存在.
2 指针的值,如果没有限制,通常是可以变化的,也可以指向另外一个地址.
地址表示内存空间的一个位置点,他是用来赋给指针的,地址本身是没有大小概念,指针指向变量的大小,取决于地址后面存放的变量类型.
但前者是可以移动的,后者是不可变的.
必须让指针指向一个有效的内存地址,
1 防止数组越界
2 防止向一块内存中拷贝过多的内容
3 防止使用空指针
4 防止改变const修改的指针
5 防止改变指向静态存储区的内容
6 防止两次释放一个指针
7 防止使用野指针.
用一个数组作为函数入参
指针P ++具体移动的字节数等于指针指向的变量类型大小.
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
**strcpy():**strcpy()函数将源字符串复制到缓冲区。没有指定要复制字符的具体数目!如果源字符串碰巧来自用户输入,且没有专门限制其大小,则有可能会造成缓冲区溢出!
解决方法:
1.如果 src 比 dst 大,则该函数不会抛出一个错误;当达到最大尺寸时,它只是停止复制字符
2.确保通过在源字符串上调用 strlen() 来分配足够的空间。
dst = (char *)malloc(strlen(src));
strcpy(dst, src);
strcat():非常类似strcpy,它可以将一个字符串合并到缓冲区末尾
解决方法:可以使用方法 fgets()。它可以做与 gets() 所做的同样的事情,但它接受用来限制读入字符数目的大小参数,因此,提供了一种防止缓冲区溢出的方法。
sprintf()、vsprintf():它们可以用直接的方式模仿 strcpy() 行为
gets()该函数从标准输入读入用户输入的一行文本,它在遇到 EOF 字符或换行字符之前,不会停止读入文本。gets() 根本不执行边界检查。因此,使用 gets() 总是有可能使任何缓冲区溢出。
解决方法:可以使用方法 fgets()。它可以做与 gets() 所做的同样的事情,但它接受用来限制读入字符数目的大小参数,因此,提供了一种防止缓冲区溢出的方法。
getchar()、fgetc()、getc()、read():如果在循环中使用这些函数,确保检查缓冲区边界
scanf()系列 : sscanf()、fscanf()、vfscanf()、vscanf()、vsscanf(),目的地缓冲区也可能会发生溢出。
解决方法:我们用设置宽度也可以解决这个问题。
方法一: 同时运行程序的两个实例。一开始两个程序的内存中数据完全相同。然后,每次让第一个实例执行一条指令,让第二个实例执行两条指令。如果程序里有死循环,那么在一定时间之后,两个实例的内存中数据又会完全相同。如果程序没有死循环,则一直到第二个实例执行完毕,两个实例的内存中数据都是不同的。
只要用一个计数变量n,表示数据不同的个数,每执行一条指令后,根据情况n++,n–或n不变即可。
方法二:在循环中打印.
缓存的好处
1. 减少了冗余的数据传输,节省了网费。
2. 减少了服务器的负担, 大大提高了网站的性能
3. 加快了客户端加载网页的速度
工作原理:
301(永久移动) 请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。
当网页A用301重定向转到网页B时,搜索引擎可以肯定网页A永久的改变位置,或者说实际上不存在了,搜索引擎就会把网页B当作唯一有效目标。
302(临时移动) 服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。会自动将请求者转到不同的位置。
304(未修改) 自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。
Tips:404 找不到
Web 服务器找不到您所请求的文件或脚本。请检查URL 以确保路径正确。 如果问题依然存在,请与服务器的管理员联系。
HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。
GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
1.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST把提交的数据则放置在是HTTP包的包体中。
2.”GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据,IIS4中最大为80KB,IIS5中为100KB”??!
3.POST比GET安全,因为数据在地址栏上不可见。
netstat命令用于显示各种网络相关信息,如网络连接,路由表,接口状态
Linux的2.2.x以后的内核版本支持多种共享内存方式,比如:内存映射mmap、POSIX共享内存、System V共享内存;
两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。
C++程序缺乏相应的手段来检测内存信息,只能使用top指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息
使用Linux命令回收内存,可以使用ps、kill两个命令检测内存使用情况和进行回收。在使用超级用户权限时使用命令“ps”,它会列出所有正在运行的程序名称和对应的进程号(PID)。
A的添加操作提交给数据库,B的删除操作提交给数据库,数据库将两个操作的结果发送给C.
int k=~0;
if((unsigned int)k >63356) cout<<"at least 32bits"<else cout<<"16 bits"<
C++把const内置类型看做常量,(g++)编译器会使用常数直接替换掉对i的引用,但结构体类型不是内置数据类型,编译器如何直接替换,因此必须要访问内存去取数据,而访问内存去取数据必然会取到被指针q改变后的值。所以没有任何机制保证了const声明的常量的不可修改性。
32位意味着4G的寻址空间(2^32),堆区最多开2G - 1大小空间栈区能开1G多,当接近2G就会报错。
1、资源不能被共享,只能由一个进程使用。
2、请求与保持条件(Hold andwait):已经得到资源的进程可以再次申请新的资源。
3、非剥夺条件(Nopre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
4、循环等待条件(Circularwait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数。exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。
1.地址映射机制:
内存分配回收机制、缓存和刷新机制、请求页机制、交换机制和内存共享机制
一般来说,程序进行输入操作有两步:
1.等待有数据可以读
2.将数据从系统内核中拷贝到程序的数据区。
对于sock编程来说:
第一步: 一般来说是等待数据从网络上传到本地。当数据包到达的时候,数据将会从网络层拷贝到内核的缓存中;
第二步: 是从内核中把数据拷贝到程序的数据区中。
1、当一个客户端需要同时处理多个文件描述符的输入输出操作的时候(一般来说是标准的输入输出和网络套接字),I/O多路复用技术将会有机会得到使用。
2、当程序需要同时进行多个套接字的操作的时候。
3、如果一个 TCP 服务器程序同时处理正在侦听网络连接的套接字和已经连接好的套接字。
4、如果一个服务器程序同时使用 TCP 和 UDP 协议。
5、如果一个服务器同时使用多种服务并且每种服务可能使用不同的协议(比如 inetd就是这样的)。
Epoll 不仅会告诉应用程序有I/0事件到来,还会告诉应用程序相关的信息,这些信息是应用程序填充的,因此根据这些信息应用程序就能直接定位到事件,而不必遍历整个FD 集合。
fork后子进程将会拥有父进程的几乎一切资源,父子进程的都各自有自己的全局变量。不能通用,不同于线程。对于线程,各个线程共享全局变量。
一个数据库存储引擎,从底层到高层,依次可能用到:堆(外存存储记录的实体):定长页和变长页。定长页使用记录长度和下标可以定位到内容,变长页头部和记录是反向存储的,根据记录下标可以定位到记录头,根据记录头定位到记录存储。索引(外存存储索引的实体):B+树内存记录缓存:分级的内存池,每块记录空间的大小固定。采用LRU或者近似淘汰算法,异步将不常用页面刷出到索引和堆。(并非所有数据库都有这一层)
建立索引,建立分区,尽量使用固定长度的字段,限制字段长度;增加缓存使用连接池;减少SQL语句的比较次数,限制返回的条目数
1、把你表中经常查询的和不常用的分开几个表,也就是横向切分
2、把不同类型的分成几个表,纵向切分
3、常用联接的建索引
4、服务器放几个硬盘,把数据、日志、索引分盘存放,这样可以提高IO吞吐率
5、用优化器,优化你的查询
6、考虑冗余,这样可以减少连接
7、可以考虑建立统计表,就是实时生成总计表,这样可以避免每次查询都统计一次
8、用极量数据测试一下 数据仓库解决的是数据挖掘,共享,和大数据量存储有什么根本关系?
将算法与具体对象分离,与类型无关,通用,节省精力
有以下几个技术:
使用定时器(适合有数据流动的情况); 使用socket选项SO_KEEPALIVE(适合没有数据流动的情况);
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
voidNoReplicatedSubstring(int s[],int len)
{
vector <int> vectTemp;
int nData= s[0];
vectTemp.push_back(nData);
for(int i=1;iif(s[i] == nData)
{
continue;
}
else
{
nData =s[i];
vectTemp.push_back(s[i]);
}
}
}
牢记红黑树的5个性质
不知道是通过心跳包来保持连接的,随便扯了下TCP的三路握手
treemap底层实现是红黑树,红黑树是一种平衡二叉树,它的时间复杂度是O(H),h为树的高度,而红黑树通过它五个性质保证了树的高度为O(logn),所以它的查询速度快
1、减少http请求,将js,css文件打包成一个文件。其实还有页面静态化,之前项目有涉及。
2、内容分发CDN,我回答的是根据用户的IP,将用户请求负载均衡到就近的数据中心。追问:如何负载均衡?可以根据IP hash生成,根据请求响应延时负载均衡。追问:这几种负载均衡属于哪种负载均衡,答不知道。他说属于软负载均衡。然后我问他还有哪种负载均衡策略。他说还有硬负载均衡。然后我再问,这样的话是不是用软件做负载均衡就是软负载,硬件做负载均衡就是硬负载。他说也可以这么理解,哈哈。最后提示我其实可以用DNS做负载均衡,这就是内容分发的思想了。
3、在每个数据中心中建立缓存。web代理的思想(详见计算机网络,潘爱民版,神书,师弟师妹不要错过)。
4、tomcat使用短连接,或者降低keep-alive时间。追问长连接和短连接的区别,哪个版本使用长连接。(此处也故意提高短连接,这是一个面试技巧,尽量提到相关的技术)。
5、数据库优化,具体方法之前问过
想了一会说是数据一致性的问题。
静态和动态,然后分别叙述了一下虚函数和函数重载
基类与派生类指针和引用的转换问题
四种情况说了一下
一个共享,一个独占引用对象。