网易Java研发笔试题(附答案)——20160322
这里的答案都是本人做的,非标准答案。如果错误,请在评论里指正,一起讨论共同进步!谢谢!
一、单选题
1. 一棵树有2个2度顶点 1个3度顶点 3个4度顶点 则其1度顶点为
A. 5 B. 7 C. 9 D. 11
【解】设1度顶点为N,则总度数= N+2*2+1*3+3*4 = N+19,树的边数= 顶点数-1= N+5,由于度数为边数的2倍,所以
N+19 = 2*(N+5),故N=9.
2.在发布-订阅(publish-subscribe)消息模型中,订阅者订阅一个主题后,当该主题有新消息达到时,所有订阅者都会受到通知。下面哪个设计模式最适合这个模型?
A. 适配器(Adapter) B. Bridge模式 C. 状态(state) D. 观察者(Observer)
3. 已知一棵二叉树,先序遍历为CABDFGE、后序遍历为BDAEGFC.求树的样子有多少种?
A. 2 B. 3 C. 4 D. 5
4.栈和队列的共同特点是
A. 只允许在端点处插入和删除元素
B. 都是先进后出
C. 都是先进先出
D. 没有共同点
5.任何一颗二叉树的叶节点在前序、中序、后序遍历序列中的相对次序
A. A和B右方
B. A是B祖先
C. A和B左方
D. A是B子孙
【解】前序是:根左右,中序是:左根右,后序是:左右根。无论怎么遍历,叶子节点的次序都是左在前右在后。
6. 在使用锁保证线程安全时,可能会出现活跃度失败的情况。活跃度失败主要包括:
A. 死锁 B. 饥饿 C. 活锁 D. 以上全部
7. 运行B.java程序,输出结果是():
A. 7,3,2,1,6,4,5
B. 3,6,7,2,1,5,4
C. 7,3,6,2,1,5,4
D. 3,2,1,7,6,5,4
【解】本文主要涉及到JVM的类加载机制,后续会详细介绍,这里只要记住:类在使用之前JVM会对其进行加载-连接-初始化,其中:
加载:将类的class文件读入内存,并为之创建一个java.lang.Class对象;
连接:检查类结构是否正确,并为类变量分配内存、设置默认的初始值;
初始化:主要是对类变量进行初始化(根据代码),覆盖原来的默认值。
如果一个类存在父类,则先初始化其父类。
8. 下面哪个表达式是不合法的?
A. List extends Number> foo = new ArrayList();
B. List super Number> foo = new ArrayList();
C. List super Integer> foo = new ArrayList();
D. List extends Integer> foo = new ArrayList();
9. 假如某个JAVA进程的JVM参数配置如下:-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3, 请问eden区最终分配的大小是多少?
A. 64M B. 500M C. 300M D. 100M
【解】JVM堆内存包括年轻代,老年代和持久代。其中年轻代又包括一个Eden区和两个Survivor区。-Xmn500M表示年轻代大小是500M,-XX:SurvivorRatio=3表示Eden区与两个Survivor区的大小比值为3:1:1,故Eden区的大小为300M
10. 下列不属于网络层协议的为
A. TCP B. IP C. IPX D. ICMP
二、多选题
11.文件aaa的访问权限为rw-r--r--,现要增加所有用户的执行权限和同组用户的写权限,下列哪些命令正确的是?
A. chmod a+x g+w aaa
B. chmod 764 aaa
C. chmod 775 aaa
D. chmod o+x g+w aaa
【解】在linux系统中,drwxrwxrwx —— 第一位表示文件类型,第一个rwx表示所有者的读/写/执行权限,第二个rwx表示同组用户的读/写/执行权限,第三个rwx表示其他用户的读/写/执行权限。根据题目要求,修改后的文件权限应该为rwxrwxr-x,即111111101
= 775。
12. ls -l显示如下:-rwxrw-r-- 1 aaa bbb 0 3月 4 11:21 ccc ,下面哪些说法是正确的?
A. 该文件是个目录
B. 该文件拥有者所在组用户有权限修改文件
C. 该文件权限的数字表示是764
D. 该文件拥有者是bbb
【解】ccc是一个文件,权限数字是764,拥有者是aaa,所在用户组是bbb,文件大小为0,最后修改时间为3月4日11:21
13.以下有关http协议描述中,哪些是正确的?
A. Post请求一般用于修改服务器上的资源,对发送的消息数据量没有限制,通过表单方式提交
B. http返回码中302表示永久重定向,需要更新URI
C. 可以通过206返回码实现断点续传
D. http1.1实现了持久连接和管线化操作以及主动通知功能,相比http1.0有大幅性能提升
【解】302表示暂时性转移。
14.以下哪个函数不能直接出现在WHERE子句中?
A. SUM B. COUNT C. ORDER BY D. GROUP BY
【解】where子句中不能有聚合函数
15.下列有关Windows系统的EXE和DLL文件说法错误的是?
A. EXE和DLL都是PE文件
B. EXE不能有导出函数,DLL可以有导出函数
C. EXE有x86和x64之分,DLL则没有
D. EXE可以单独运行,DLL则不行
【解】PE文件的全称是PortableExecutable,意为可移植的执行体是,常见的EXE、DLL、OCX、SYS、COM等。EXE是可执行文件,DLL是动态链接库,它们都可以有导出函数,且都有x86和x64之分。
16.假设系统按单道方式运行且采用短作业优先算法,有J1,J2,J3,J4 共4个作业同时到达,则以下哪几种情况下的平均周转时间为10分钟?
A. 执行时间:J1: 1分钟 J2: 5分钟 J3: 9分钟 J4: 13分钟
B. 执行时间:J1: 1分钟 J2: 4分钟 J3: 7分钟 J4: 10分钟
C. 执行时间:J1: 2分钟 J2: 4分钟 J3: 6分钟 J4: 8分钟
D. 执行时间:J1: 3分钟 J2: 6分钟 J3: 9分钟 J4: 12分钟
【解】以A选项为例:四个作业同时达到,由于采用单道方式运行且短作业优先,J1无需等待,执行1分钟完成;J2等待1分钟,执行5分钟完成;J3等待6分钟,执行9分钟完成;J4等待15分钟,执行13分钟完成。—— 故四个作业平均周转时间为:(J1*4+J2*3+J3*2+J4)/4
17. 以下哪些事件会直接导致Linux系统从用户态切换到内核态?
A. 响应硬件中断
B. 编译程序源码
C. 执行系统调用
D. 查看系统日志
【解】系统调用、硬件中断会触发用户态到内核态的切换。
18. 以下说法中正确的有?
A. StringBuilder是线程不安全的
B. Java类可以同时用abstract和final声明
C. HashMap中,使用 get(key)==null可以判断这个Hasmap是否包含这个key
D. volatile关键字不保证对变量操作的原子性
【解】StringBuilder是线程不安全的,StringBuffer是线程安全的;volatile保证变量对线程的可见性,但不保证原子性;HashMap是允许插入null键/null值的,如果本就存在某个key的值为null,那么并不能判断。
19. 下列哪些类型能被throw语句抛出?
A. Error B. Exception C. Throwable D. Object
【解】注意Error也是可以被throw的,只是通常Error出现程序就中断了,我们并不会去捕获。
20.以下不同的数据库类型中,哪些不属于关系型数据库范畴?
A. MongoDB B. PostgreSQL C. Redis D. HBase
三、主观题
21. Java如何进行序列化
【解】Java中如果想要将某个对象序列化,该对象的类需要实现Serializable接口或者实现Externalizable接口。不同的是:实现Serializable接口无须实现任何方法,而实现Externalizable接口则必须为
writeExternal() 和 readExternal() 两个空方法提供实现。—— 在目标类实现了接口以后,就可以通过 ObjectOutputStream 将目标类对象进行序列化并输出了。
22. Exception,Error,RuntimeException在java异常处理中有什么不同
【解】Java中的异常分为 Error 和 Exception。其中Error一般指与虚拟机相关的错误,如系统崩溃、虚拟机错误、动态链接失败等,应用程序无法处理这些错误;Exception则是指应用程序本身可以处理的异常,它分为Checked
Exception和RuntimeException —— Checked异常,也叫编译时异常,Java编译器强制要求我们必须对出现的这种异常进行catch处理,否则程序就不能编译通过;RuntimeException,即运行时异常,编译器不会检查运行时异常,我们也可以不处理,当出现这样的异常时,总是抛出由虚拟机接管。当然运行时异常也是可以catch的。
23. wait(), notify()和notifyAll()在使用的时候需要放在同步方法/代码块中吗?为什么?
【解】需要放在同步方法/同步代码块中,因为这三个方法必须由同步监视器对象来调用。在同步代码块中,同步监视器对象就是 synchronized() 括号中的对象;在同步方法中,同步监视器对象则是隐式的当前对象
this。—— 在调用wait()之前,当前线程已经通过synchronized获得了同步监视器的对象锁,调用了wait()以后,线程进入阻塞状态,并释放对象锁;其他线程获得了同步监视器的对象锁以后,就开始执行它的同步方法/代码块了,在同步方法/代码块中如果调用了notify(),则会唤醒在同步监视器对象上wait的任一线程,等剩余的代码执行完后,释放对象锁;被唤醒的线程尝试获取对象锁,获取到了以后线程继续向下执行。notifyAll()和notify()类似,只不过notifyAll()是唤醒在同步监视器对象上wait的所有线程,这些线程后续会争夺对象锁,谁得到对象锁谁继续执行。
24. 编程:给定两个字符串A,B(只包含26个英文字母),输出所有公共的最长子字符串(如果出现重复子串,则输出多次)
输入包括两行,每行为一个连续字符串(大小写敏感)
输出包括多行,每行为扫描到的最长公共子串,按照该子串在字符串A(即第一行输入字符串)中出现的先后次序输出
样例输入:
abcxyzabcrst
opqrstabc
样例输出:
abc
abc
rst
【解】见文《华为OJ2011-最长公共子串》与最长公共子序列一样,最长公共子串也可以采用动态规划(打表)进行求解。举个例子:X
= bab,Y = caba。打表如下:
具体打表的方法是:
第一行、第一列初始化为 0;
对于其他的格子:
若对应的两个字符相等,格子的值设为左上角的值加 1。
若对应的两个字符不相等,直接置 0 。
#include
#include
#include
using namespace std;
int main() {
string X, Y;
getline(cin, X);
getline(cin, Y);
int m = X.length();
int n = Y.length();
vector > table(m+1, vector(n+1));
int biggest = 0; // 记录表中的最大值
vector > firstPos; // 记录子串开始的坐标
for(int i=0; i
{
for(int j=0; j
{
if(i==0 || j==0) // 第一行和第一列置0
table[i][j]=0;
else if(X[i-1] == Y[j-1])
{
table[i][j] = table[i-1][j-1] + 1;
if(table[i][j] > biggest)
biggest = table[i][j];
if(table[i][j] == 1)
firstPos.push_back(make_pair(i, j));
}
else
table[i][j] = 0;
}
}
// 以下输出所有最长公共子串
vector >::iterator it = firstPos.begin();
for( ; it!=firstPos.end(); ++it)
{
int startX = it->first-1;
int startY = it->second-1;
if(X.substr(startX,biggest) == Y.substr(startY,biggest))
cout << X.substr(startX, biggest) << endl;
}
}
25. 编程:在一个整数的数组中删除另外一个整数数组中的元素,并保留原数组的次序
输入包括两行:
1. 第一行是被删除的整数列表(记为列表A),每个整数之间使用空格分隔
2. 第二行是需要删除的整数列表(记为列表B),每个整数之间使用空格分隔
输出只有一行,即列表A中删除列表B元素后的整数列表,输出元素按照在列表A中的次序排列,每个整数之间使用空格分隔
样例输入:
1 2 3 4 5
2 4
样例输出:
1 3 5
【解】本题较简单,获取第一行时,用一个list保存;获取第二行时,将每个数从list中删除,最后输出即可。
#include
#include
#include
#include
using namespace std;
int main() {
list mylist;
for(int i=0; i<2; ++i) {
int n;
string str;
getline(cin, str);
stringstream ss(str);
while(!ss.eof()) {
ss >> n;
if(i==0)
mylist.push_back(n);
else
mylist.erase(find(mylist.begin(),mylist.end(),n));
}
ss.clear();
}
list::iterator it = mylist.begin();
for( ;it!=mylist.end(); ++it) {
cout << *it << " ";
}
}