单选
1.主机甲与主机乙之间已建立一个TCP连接,主机甲向主机乙发送了两个连续的TCP段,分别包含300B和500B的有效载荷,第一个段的序列号为200,主机乙正确接收到这两个数据段后,发送给主机甲的确认序列号是
A.200;B.500;C800;D.1000
答案:D
解析:
确认序列号=原始序列号+TCP段的长度
第一次的确认序列号为200+300=500,第二次确认序列号为500+500=1000
2.在支持多线程的系统中,进程P创建的若干个线程不能共享的是
A.进程P的代码段
B.进程P中打开的文件
C.进程P的全局变量
D.进程P中某线程的栈指针
答案:D
解析:
1.堆 由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)
2.全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
3.静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
4.文件等公用资源 这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。
独享的资源有
5.栈 栈是独享的
6. 寄存器 这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC
3.排序算法的效率取决于元素的比较次数与元素的位置移动次数,现需要对数组进行升序排序,已知一数组的元素为{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},问下面哪种排序算法的效率最高?
A.插入排序;B.选择排序;C.快速排序;D.冒泡排序
答案:A
解析:
插入排序在数组有序时效率最高,因为每次只需要和上一个元素比较,不用移动元素
就这道题目而言,
1.如果插入排序每次插入都是在已有序序列的头部开始向后移动比较的话,需要比较(1+9)*9/2=45次;如果插入排序每次插入都是在已有序序列的尾部开始向前移动比较的话,需要比较9次。
2.选择排序需要比较(1+8)*8/2=36次。
3.优化的冒泡排序可以做到序列事先有序的情况下比较9次返回。
4.一个栈的入栈序列是a b c d e,则栈的输出序列不可能是
A.dceab
B.decba
C.edcba
D.abcde
答案:A
5.对数据库,关于索引的理解正确的是
A.创建索引能提高数据插入的性能
B.索引应该根据具体的检索需求来创建,在选择性好的列上创建索引
C.索引并非越多越好
D.建立索引可加速查询
答案:B C D
6.用浏览器访问一个Internet网站,可能使用到的协议有
A.PPP;B.HTTP;C.POP;D.ARP
答案:A B D
解析:
物理层:RJ45、CLOCK、IEEE802.3(中继器,集线器,网关)
数据链路:PPP、FR、HDLC、VLAN、MAC(网桥,交换机)
网络层:IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP、(路由器)
传输层:TCP、UDP、SPX
会话层:NFS、SQL、NETBIOS、RPC
表示层:JPEG、MPEG、ASII
应用层:FTP、DNS、Telnet、SMTP、HTTP、WWW、NFS
访问网络时,会用到以下协议。
PPP:点对点协议
ARP:地址解析协议
HTTP: 超文本传输协议
但是不会用到POP:电子邮箱协议
7.查找或删除性能较低的数据结构有
A.有序数组
B.有序链表
C.AVL树
D.Hash表
答案:A B
8.以下哪些与编译器的任务有关?
A.公共子表达式合并
B.运行程序前加载其依赖的动态库
C.尾递归优化
D.常量、不变式预计算
答案:A C D
解析:
这道题目涉及到编译方面的内容,代码转变到可执行文件过程经过编译器,汇编器和链接器,他们各自的任务如下:
1.编译器:读取源程序,进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,中间还进行优化等处理;
2.汇编器:把汇编语言代码翻译成目标机器指令,关键是目标代码的分段处理;
3.链接器:将有关的目标文件彼此相连接生成可加载、可执行的目标文件。
9.现有代码如下,则 func(5)的返回值为:
int func(int n){
if(n <= 1){
return 1;
}else{
return n * func(n-1);
}
}
答案:120
10.下面C程序的运行打印结果是:
#include <stdio.h>
int main(int argc, char** argv) {
char* array[] = {"hello", "my", "world", "goodbye"};
char** p = array;
p = p + 2;
printf("%s", *p);
return 0;
}
答案:world
11.一个长度为100的循环链表,指针A和指针B都指向了链表中的同一个节点,A以步长为1向前移动,B以步长为3向前移动,最少需要同时移动1步A和B才能再次指向同一个节点
答案:50
解析:
设X步后相遇,必定是B比A多跑一圈那么就有3X - 100 = X,X=50
12.一棵完全二叉树中有33个结点,则该完全二叉树的深度为1
答案:6
13.{0, 2, 1, 4, 3, 9, 5, 8, 6, 7}是以数组形式存储的最小堆,删除堆顶元素0后的堆的新结果是1(结果需要英文逗号分隔)
答案:1,2,5,4,3,9,7,8,6
解析:
最小堆的下层是将两个子节点较小的与之比较,然后交换,依次向下比较交换
13.已知关键字序列为(51,22,83,46,75,18,68,30),进行快速排序,第一趟按关键码字51进行,完成后的序列为
答案:30,22,18,46,51,75,68,83
14.LRU的cache长度为3,初始为空。依次访问如下元素后,cache里的内容是(结果需要英文逗号分隔)
A,A,B,C,A,D,C,E
答案:E,C,D
15.已知一算数表达式的中缀表达式为 a-(b+c/d)*e
,其后缀形式为
答案:abcd/+e*-
16.从1 - 1001中,能被数字2或者数字3或者数字5整除的数字有1个
答案:734
解析:
1-1001之间被2整除的数字有500个,被3整除的数字有333个,被5整除的数组有200个,共1033个
我们要去掉一些重复的,能被2整除且能被3整除的也就是能被6整除的共166个
能被2整除且能被5整除的也就是能被10整除的共100个
还有能被3整除且能被5整除的也就是能被15整除的共66个
如果直接用1033减去这三个值,我们会多减去能被2同时能被3同时能被5整除的也就是能被30整除的数字(共33),所以我们最后必须加上这33个.
1033-166-100-66+33 = 734
17.5个盒子每个里面各有一个球,把球全拿出来打乱再放回去,每个球都不在自己原来的盒子里,有1种可能
答案:44
解析:
排除法。包括球在原来自己的盒子的可能一共是5的阶乘=120种。
1、有五个球都在自己的盒子里,1种。
2、有四个球在自己的盒子里,不存在,0种。
3、有三个球在自己的盒子里,只有两个对调了,5×4/2,10种。
4、有二个球在自己的盒子里,5×4/2×2,20种。
5、有一个球在自己的盒子里,5×(24-1-6-4×2),45种。(递归)
120-45-20-10-1=44种。
18.当用分支覆盖法对以下流程图进行测试时,至少需要设计1个测试用例
答案:6
解析:
b可能有3个值 b=0;b>0;b<0;
a可能有2个值 a>=0;a<0;
2*3=6 ,一共有6种情况
19.在所有非抢占CPU调度算法中,系统平均响应时间最优的是()
A.实时调度算法;B.短任务优先算法;C.时间片轮转算法;D.先来先服务算法
答案:B
解析:
短任务优先系统平均响应时间最短,但是往往不能确定所有任务的运行时间
先来先服务平均响应时间最长,不适用于分时系统
时间片轮转,适用于分时系统,但是增加了抢占以切换进程,算法性能依赖于时间片大小
20.磁盘进行读写操作的物理单位是:
答案:扇区
解析:
磁盘读写基本单位是扇区,操作系统是通过块和簇来做为单位读取等操作数据的。扇区是对硬盘而言,是物理层的,块和簇是对文件系统而言,是逻辑层的。
21.幼儿园扩建需要制作一批新的玩具,幼儿园老师做了一个边长10cm的立方体,表面涂满油漆,现在将它切割成边长为0.2cm的小立方体,问两个面有油漆的小立方体有多少个()
A 576;B 456;C 624;D 568
答案:A
解析:
只有两面涂满油漆,则一个边长长有50个立方体组成,去掉两个顶点(因为顶点是三面涂满油漆),为48个,涂满两面油漆的边共有12个,则 12 * 48 = 576
22.在下图中,从顶点()出发存在一条路径可以遍历图中的每条边一次,而且仅遍历一次
A点;B点;C点;D点;E点
答案:E点
23.哪种密钥用来传输数据()
A.半对称密钥技术;B.非对称密钥技术
C.全对称密钥技术;D.对称密钥技术;
答案:D
24.用有向无环图描述表达式(A+B)*((A+B)/A),至少需要顶点的数目为()
A.8;B.5;C.6;D.9
答案:B
解析:
看一个例子,就是将一个表达式转化成二叉树,再将二叉树去重转换成有向无环图。这里的重指的是节点的重:
同理可得该题:
所以总共是5个顶点。
25.初始序列号为1 8 6 2 5 4 7 3一组数采用堆排序,当建堆(小顶堆)完毕时,堆所对应的二叉树中序遍历序列为()。
A.8 3 2 5 1 6 4 7;B.3 2 8 5 1 4 6 7
C.3 8 2 5 1 6 7 4;D.8 2 3 5 1 4 7 6
答案:A
解析:
26.下列最短路径算法的叙述中正确的是()
A.Dijkstra算法通常用于求每一对顶点间的最短路径;
B.Dijkstra算法不允许图中带有负权值的边,而Floyd算法则可以适用;
C.Floyd算法通常用于求某一顶点到其他各顶点的最短路径;
D.Floyd算法允许有包含负权值的边组成的回路,而Dijkstra算法不允许;
答案:B
解析:
1.Dijkstra算法是计算图中的一个点到其它点的最小路径,算法思路: 贪心算法。
2.Floyd算法计算图中任意一对点的最短路径,算法思路: 动态规划法,T(n)=O(n^3)。
3.Dijkstra算法为啥不能存在负数边?Dijkstra中S(已求出解)中的每一个点解即最短路径是已求出的,若存在负数路径,可能存在已求出的解不是最优解.
27.数据连接层的错误检测时通过什么实现的
28.在osi模型中,以下那一层负责为用户提供可靠的节点到节点服务()
A. 会话层
B. 传输层
C. 网络层
D. 数据链路层
答案:B
解析:osi参考模型中负责为用户提供可靠的节点到节点服务是传输层。
29.S市A,B共有两个区,人口比例为3:5,据历史统计A的犯罪率为0.01%,B区为0.015%,现有一起新案件发生在S市,那么案件发生在A区的可能性有多大?()
A.37.5%;B.32.5%;C.28.6%;D.26.1%
答案:C
解析:
思路一:
含有%的概率题,可以实例化是最好的方式。故而,B区5000人,A区3000人,A区30个罪犯,B区75个罪犯。那么狠显然30/(30+75)=0.2857,就是C。
思路二:
数学解析过程如下:
C表示犯案属性
在A区犯案概率:P(C|A)=0.01%
在B区犯案概率:P(C|B)=0.015%
在A区概率:P(A)=3/8
在B区概率:P(B)=5/8
犯案概率:P(C)=(3/8*0.01%+5/8*0.015%)
则犯案且在A区的概率:P(A|C)=P(C|A)*P(A)/P(C)=0.01%*(3/8)/(3/8*0.01%+5/8*0.015%)≈28.6%
30.在下列情况()要进行进度调度。
A. 某一进程正访问一临界资源
B.某一进程运行时因缺乏资源进入阻塞状态
C.某一进程处于运行状态,而另一进程处于自由状态
D.某一进程正在访问打印机,而另一进程处于就绪状态
答案:B
31.数据包序列使用4位,最大窗口为:15
32.用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整型数()
A.int *a[10];B.int (*a)[10];
C.int (*a)(int);D.int (*a[10])(int);
答案:D
解析:
int *a[10]; //指向int类型的指针数组a[10]
int (*a)[10]; //指向有10个int类型数组的指针a
int (*a)(int);//函数指针,指向有一个参数并且返回类型 均为int的函数
int (*a[10])(int); //函数指针的数组,指向有一个参数并且返回类型均为int的函数的数组
33.虚拟内存容量受什么限制
答案:硬盘
解析:
虚拟内存容量只受硬盘剩余空间的限制。
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
34.回溯法的含义是指加剪枝的深度优先展开方法,这样的说法正确吗?
答案:正确
解析:
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点"。
深度优先搜索是采用递归的方法,先沿一条路搜到底,再递归回上一个节点,沿另一个方向搜索,以此类推。
剪枝,属于算法优化范畴;通常应用在DFS 和 BFS 搜索算法中;剪枝策略就是寻找过滤条件,提前减少不必要的搜索路径。
剪枝分为可行性剪枝、最优性剪枝、记忆化搜索、搜索顺序剪枝。
最优性剪枝,如果当前花费已经超过当前搜索最优解,那么无论之后采取多么优秀的策略到达递归边界都不肯能更新答案。
极端法:通过对当前节点进行理想式扩展,通过否定这样的情况来避免对当前的节点扩展;
调整法:基本思想通过对子树的比较剪掉重复子树和明显不是最有前途的子树;
数学方法:利用专门剪枝知识,借助数学模型;
可行性剪枝:该方法判断继续搜索能否得出答案,如果不能直接回溯。
综上,回溯法就是带剪枝的dfs
35.用两种颜色去染排成一个圈的6个棋子,如果通过旋转得到则只算一种,问一共有多少种染色方式
答案:14
解析:
假设有两种颜色AB,那么两种颜色的个数为P(m,n)
则全A或者全B各有一种:P(6,0)=P(0,6)=1,共2种
P(5,1)=P(1,5)=1,共2种
P(4,2)=P(2,4)=3,共6种//相邻的一种AABBBB,隔一个的一种ABABBB,两个的一种ABBABB
P(3,3)=4共4种//相邻的一种ABABAB,还有ABAABB,AABABB,AAABBB,
所以一共有:2+2+6+4=14种
36.Ping 127.0.0.1 这个命令数据包被送到()
A.远端服务器;B本机;C.Internet;D. 网关;
答案:B
37.minor gc 和 full gc 的区别
新生代 GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具
备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
老年代 GC(Major GC / Full GC):指发生在老年代的 GC,出现了 Major GC,经常
会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里
就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度一般会比 Minor GC 慢 10
倍以上。
Minor GC触发机制:
当年轻代满时就会触发Minor GC,这里的年轻代满指的是 Eden 代满, Survivor 满不会引发 GC
Full GC触发机制:
当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代,
当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载。
38.javaweb应用会话跟踪技术
-
Cookie:可以使用 cookie 存储购物会话的 ID;在后续连接中,取出当前的会话 ID,并使用这个 ID 从服务器上的查找表(lookup table)中提取出会话的相关信息。 以这种方式使用 cookie 是一种绝佳的解决方案,也是在处理会话时最常使用的方式。但是,sevlet 中最好有一种高级的 API 来处理所有这些任务,以及下面这些冗长乏味的任务:从众多的其他cookie中(毕竟可能会存在许多cookie)提取出存储会话标识符的 cookie;确定空闲会话什么时候过期,并回收它们;将散列表与每个请求关联起来;生成惟一的会话标识符.
-
URL重写:采用这种方式时,客户程序在每个URL的尾部添加一些额外数据。这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。 URL重写是比较不错的会话跟踪解决方案,即使浏览器不支持 cookie 或在用户禁用 cookie 的情况下,这种方案也能够工作。
URL 重写具有 cookie 所具有的同样缺点,也就是说,服务器端程序要做许多简单但是冗长乏味的处理任务。即使有高层的 API 可以处理大部分的细节,仍须十分小心每个引用你的站点的 URL ,以及那些返回给用户的 URL。即使通过间接手段,比如服务器重定向中的 Location 字段,都要添加额外的信息。这种限制意味着,在你的站点上不能有任何静态 HTML 页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此,每个页面都必须使用 servlet 或 JSP 动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接再次回来,会话的信息也会丢失,因为存储下来的链接含有错误的标识信息。 -
隐藏的表单域:HTML 表单中可以含有如下的条目:
这个条目的意思是:在提交表单时,要将指定的名称和值自动包括在 GET 或 POST 数据中。这个隐藏域可以用来存储有关会话的信息,但它的主要缺点是:仅当每个页面都是由表单提交而动态生成时,才能使用这种方法。单击常规的超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程。 -
session:信息保存在服务器端;使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话
39.redis数据类型使用场景
string
场景:作为常规的key-value缓存应用。例如微博数、粉丝数等。注:一个键最大能存储512MB
hash
hash是一个string类型的field和value的映射表,hash特别适合用于存储对象(应为对象可能会包含很多属性)
场景:主要用来存储对象信息
list
list列表是简单的字符串列表,按照插入顺序排序(内部实现为LinkedList),可以选择将一个链表插入到头部或尾部。
应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
set
是一种无序的集合,集合中的元素没有先后顺序,不重复。将重复的元素放入Set会自动去重。
应用场景:某些需要去重的列表,
sort set
有序集合,相比set,元素放入集合时还要提供该元素的分数,可根据分数自动排序。
应用场景:排行榜
问答题
1.考虑一个网络服务,希望具备防刷的安全特性。假设要求策略是对每次请求访问,如果该请求的来源IP,在当前的前N秒内已经请求过了M次,则拒绝服务X秒。请设计方案,无需写出完全代码,描述清楚设计实现即可。并请针对设计出的方案分析利弊
答案:
每个IP关联一个最近访问时间戳T,和一个链表L,链表元素为一个细粒度时间段内的访问次数,比如粒度定为500毫秒,则链表内元素依次代表了该IP当前500毫秒的(开始时间,结束时间,请求次数),往前的500毫秒中(开始时间,结束时间,请求次数),再往前500毫秒的(开始时间,结束时间,请求次数)…相邻元素的时间段不一定需要连续。
用hash关联IP保存所有T和L
对每一个来访请求,按IP从hash中找到关联的链表L,将最新的元素计数加1(根据当前时间决定是否创建新元素),将N秒前的元素删除,如果剩余元素的计数之和大于等于M,并且最近访问时间戳T到当前未超过X秒,则拒绝服务,否则更新T并提供服务。
定时器将过期IP数据从hash中删除
处理过程中使用同步结构,保证并发安全。
你用微信(或QQ)app给中意的她(他)发送了一句表白,很快收到了一句回复“呵呵”。从你输入完消息点下“发送”按钮,到“呵呵”呈现出来的这段时间,你的手机系统里发生了哪些事情?请根据你所学的计算机知识,尽可能详细的解释。(提示:从软硬件的尽量多的层次考虑和描述。)
答案:
键盘硬件中断;OS处理中断,转换为特定消息放入浏览器程序的事件队列;浏览器的消息循环处理该消息,请求网址;OS请求本地域名缓存或域名服务器解析网址中的域名,得到IP;浏览器向该IP建立TCP连接(默认80端口);浏览器发送GET请求,包含网站的路径,TCP协议栈组装为TCP包,通过网卡发送;浏览器等待网站回复,进程被OS切换为等待状态;网站返回的数据到来,网卡产生中断;OS处理中断,TCP协议栈将数据读入buffer;浏览器获得数据,处理HTTP头,显示HTML网页
更多:OS发ARP包获得网关MAC地址,所有DNS请求、网站TCP等数据包均发向该网关;浏览器IO等待期间OS切换运行系统中其他进程;浏览器将HTTP头中解析出的cookie保存到文件系统;根据网页内容发起更多的HTTP请求获取图片、运行内嵌的javascript脚本等;将网页按照HTTP 头的指示缓存;将网址加入浏览历史保存到文件系统;浏览器整个处理过程中,运行库和OS对内存做相应分配释放,磁盘做相应的IO操作;。。。
编程
给定一个可能含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。
1.单调找结构进阶
/*
单调栈结构
*/
public static void result(int []nums, int n){
//long startTime = System.nanoTime(); //获取开始时间
StringBuilder s = new StringBuilder();
int idx = 0;
for(int i = 0; i < n; i++){
int left = i - 1, right = i + 1;
// int []res = new int[2];
// res[0] = res[1] = -1;
// 左边
idx = -1;
while(left >= 0){
if(left >= 0 && nums[left] < nums[i]){
//res[0] = left;
idx = left;
break;
}
left--;
}
s.append(idx + " ");
// 右边
idx = -1;
while(right < n){
if(right < n && nums[right] < nums[i]){
//res[1] = right;
idx = right;
break;
}
right++;
}
s.append(idx + "\n");
}
System.out.println(s.toString());
//long endTime = System.nanoTime(); //获取结束时间
//System.out.println("程序运行时间: "+ (endTime - startTime) + "ns");
}
/*
单调栈结构(进阶)(时间要求更高了)
*/
public static void result2(int []nums, int n){
//long startTime = System.nanoTime(); //获取开始时间
int idx = 0;
StringBuilder s = new StringBuilder();
for (int i = 0; i < n; i++){
if (i == 0){
idx = -1;
}else{
for (int j = i - 1; j >= 0; j--){
idx = -1;
if (nums[j] < nums[i]){
idx = j;
break;
}
}
}
s.append(idx + " ");
if (i == n-1){
idx = -1;
}else{
for (int j = i; j < n; j++){
idx = -1;
if (nums[j] < nums[i]){
idx = j;
break;
}
}
}
s.append(idx+ "\n");
}
System.out.println(s.toString());
//long endTime = System.nanoTime(); //获取结束时间
//System.out.println("程序运行时间: "+ (endTime - startTime) + "ns");
}
2.0左边必有1的二进制字符串的数量
给定一个整数n,求由“0”字符和“1”字符组成的长度为n的所有字符串中,满足“0”字符的左边必有“1”字符的字符串的数量。
/*
动态规划
1 -> 1
2 -> 2
3 -> 3
4 -> 5
*/
public static int getNum(int n){
if (n < 1){
return 0;
}
int []dp = new int[n+1];
dp[0] = 1;
dp[1] = 2;
for (int i = 2; i < n; i++){
dp[i] = (dp[i-1] + dp[i-2]) % (int)Math.pow(2, 29);
}
return dp[n-1];
}