首页 > 代码库 > 2014腾讯实习笔试内容
2014腾讯实习笔试内容
1. 网络:
TCP/IP协议栈各个层次及分别的功能
应用层:协议栈的最上层,针对不同的应用提供不同的协议,例如文件传输FTP,网页请求HTTP等等;
传输层:负责数据的传输和数据的控制,主要是TCP/UDP协议;
网络层:处理分组在网络中的活动,例如路由选择和转发等,这一层主要包括IP协议、ARP、ICMP协议等;
网络接口层:协议栈的最底层,对应OSI的物理层和数据链路层,主要完成数据帧的实际发送和接收。
2. 数据库
- 事务的四大特性
原子性(A):事务是原子的工作单元,对于数据的操作,要不全都执行,要不全都不执行;
一致性(C):事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。
隔离性(I):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。
持久性(D):事务完成之后,它对于系统的影响是永久性的。
- 用MySQL语法建 一个学生表,包括学生姓名、性别、年龄、班级信息。
- char()与varchar()的区分,什么情况下用char()?(两者区别很重要)
char():定长字符串,例如char(n),当输入字符小于n时,数据库自动补全到n个字符,当输入字符大于n时,数据库自动截断多余的字符;
varchar():变长字符串。
- 建过索引吗?什么情况下需要建立索引?
什么情况下设置索引
动作描述 | 使用聚集索引 | 使用非聚集索引 |
外键列 | 应 | 应 |
主键列 | 应 | 应 |
列经常被分组排序(order by) | 应 | 应 |
返回某范围内的数据 | 应 | 不应 |
小数目的不同值 | 应 | 不应 |
大数目的不同值 | 不应 | 应 |
频繁更新的列 | 不应 | 应 |
频繁修改索引列 | 不应 | 应 |
一个或极少不同值 | 不应 | 不应 |
建立索引的原则:
1) 定义主键的数据列一定要建立索引。
2) 定义有外键的数据列一定要建立索引。
3) 对于经常查询的数据列最好建立索引。
4) 对于需要在指定范围内的快速或频繁查询的数据列;
5) 经常用在WHERE子句中的数据列。
6) 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。
7) 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
8) 对于定义为text、image和bit的数据类型的列不要建立索引。
9) 对于经常存取的列避免建立索引
9) 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
10) 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字 段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高 的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。
- 索引的作用?为什么能够提高查询速度?(索引的原理)
索引分为聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间!
索引的原理:先对数据列进行排列,从而有助于更快地获取数据库记录信息!
- 索引有什么副作用吗?
耗费存储空间、插入和删除数据记录需要更多的时间!因此不应该在经常变动的列上建立索引!
- 在sql语句中加上字符集的方法。(不理解要问什么)
3. 语言类
- sizeof 的使用
struct Test { int a; char b; short c;};
sizeof(Test)=? 8
Test test;
sizeof(test)=? 8
- static 的作用(区分C语言和C++,两种语言下作用有所不同)
C:1)隐藏:所有未加 static 前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。加有 static 前缀的全局变量和函数则只对当前文件可见!
2)保持变量内容的持久性:带有 static 前缀的变量将存储在静态数据区,在程序刚开始运行时便完成初始化,也是唯一的一次初始化!例如,函数内的static变量的赋值语句是不会被执行的(除了第一次初始化)!
3)默认初始化:因为static 变量存储在 静态数据区,因此,变量都会默认初始化为0x00
C++:1)静态数据成员:
2)静态函数成员:都是与类实例无关的成员,只与类本身相关,因此不存在生存期间的问题!
- volatile 关键字的作用
volatile 的本意是“易变的” 因为访问寄存器要比访问内存单元快的多,所以编译器一般都会作减少存取内存的优化,但有可能会读脏数据。当要求使用 volatile 声明变量值的时候,系统总是重新从它所在的内存读取数据,即告诉编译器别做优化!
- 智能指针的分类及实现原理
分类:auto_ptr、unique_ptr、shared_ptr和weak_ptr,详细请看:C++之智能指针
实现原理:将指针封装在类当中,并重载相关的操作符(* -> 等),在类的 destructor 中 delete 指针,智能指针的不同在于如何控制指针的释放!
- 多个链表怎么进行归并排序
稍后奉上答案!
- 快排、堆排的时间复杂度比较,如果不考虑空间复杂度,为什么说快排的的平均性能比堆排好?(汗,这个问题当时真不知道,后来回来看算法导论,上面是说快排的时间复杂度常数因子比堆排小,不知道还有其它什么原因。)
- 写出数字1234转成字符串"1234"的函数( itoa ),反过来的函数( atoi )。
/************************************************************************* > File Name: itoa.c > Author: ma6174 > Mail: ma6174@163.com > Created Time: Tue 27 Jan 2015 08:02:01 PM HKT ************************************************************************/#include<stdio.h>#include <stdlib.h>char* itoa(int num,char *str,int radix){ /*索引表*/ char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; unsigned unum;/*中间变量*/ int i = 0, j, k; /*确定unum的值*/ if(radix == 10 && num < 0)/*十进制负数*/ { unum = (unsigned)-num; str[i++]=‘-‘; } else unum = (unsigned)num;/*其他情况*/ /*转换*/ do { str[i++] = index[unum % (unsigned)radix]; unum /= radix; }while(unum); str[i]=‘\0‘; /*逆序*/ if(str[0] == ‘-‘) k = 1;/*十进制负数*/ else k = 0; char temp; for(j = k; j <= (i-1)/2; j++) { temp = str[j]; str[j] = str[i - 1 + k - j]; str[i - 1 + k - j] = temp; } return str;}int atoi(char* pstr) { int Ret_Integer = 0; int Integer_sign = 1; /* * 判断指针是否为空 */ if(pstr == NULL) { printf("Pointer is NULL\n"); return 0; } /* * 跳过前面的空格字符 */ while(isspace(*pstr) == 0) { pstr++; } /* * 判断正负号 * 如果是正号,指针指向下一个字符 * 如果是符号,把符号标记为Integer_sign置-1,然后再把指针指向下一个字符 */ if(*pstr == ‘-‘) { Integer_sign = -1; } if(*pstr == ‘-‘ || *pstr == ‘+‘) { pstr++; } /* * 把数字字符串逐个转换成整数,并把最后转换好的整数赋给Ret_Integer */ while(*pstr >= ‘0‘ && *pstr <= ‘9‘) { Ret_Integer = Ret_Integer * 10 + *pstr - ‘0‘; pstr++; } Ret_Integer = Integer_sign * Ret_Integer; return Ret_Integer; } int main(){ int number = -123456; char string[25]; itoa(number, string, 10); printf("integer=%d, string=%s\n", number, string); char a[] = "-100"; char b[] = "456"; int c = 0; int atoi(char*); c = atoi(a) + atoi(b); printf("atoi(a)=%d\n",atoi(a)); printf("atoi(b)=%d\n",atoi(b)); printf("c = %d\n",c); return 0;}
- Makefile的相关内容:如何指定头文件的路径,库的路径,如何指定特定的库。
- gdb 如何进行调试。
稍后奉上答案!
4. Linux
- 会Linux开发吗?会shell脚本吗?比如 grep、awk,然后给了一个实用场景,让用grep或awk进行文本处理。
grep命令:用于查找,例如进程的查找:ps -ef | grep friefox
awk命令:强大的文本分析工具,awk在其对数据分析并生成报告时,显得尤为强大。简单来说 awk 就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
- Linux常用命令的用法
5. Coding
求一个单链表的中间节点,要求安全检查,能直接运行的程序。(很简单,但能写出无bug、完全能运行的程序也不是非常容易,要注意边界检查、指针是否为空、特殊情况、编码风格、是否有注释等)。
6. 操作系统
- 进程调度设计需要考虑的问题,有哪些调度算法?
进程调度设计需要考虑的问题:资源(内存、CPU、IO设备、锁等等)的分配,
调度算法:1)First Come First Served;2)基于优先级的调度算法;3)最短作业优先调度算法(最优的调度算法);4)循环调度算法,在FCFS基础上加入了抢占;5)多层次队列调度!
- 内核中与进程管理相关的数据结构
- 画出文件系统的体系结构图,缓存位于哪一层?
- 画出内存管理的框架图,malloc 如何分配内存?
- 画出进程的地址空间的分布图
- 进程间通信( IPC )有哪些方式?
1)管道;历史上,它们是半双工的,现在某些系统提供全双工的管道,但是为了最佳的可移植性,不能假设管道全都是全双工的;管道只能在具有共同祖先的两个进程间使用!
2)消息队列(消息的链表);存储在内核中,由消息队列标识符标记。链表的长度受限
3)信号量;
4)共享存储;
5)FIFO;
7. 算法
树的遍历方法与算法
2014腾讯实习笔试内容