网易笔试题01

1. Java如何进行序列化

【解】Java中如果想要将某个对象序列化,该对象的类需要实现Serializable接口或者实现Externalizable接口。不同的是:实现Serializable接口无须实现任何方法,而实现Externalizable接口则必须为 writeExternal() 和 readExternal() 两个空方法提供实现。—— 在目标类实现了接口以后,就可以通过 ObjectOutputStream 将目标类对象进行序列化并输出了。

2. Exception,Error,RuntimeException在java异常处理中有什么不同

【解】Java中的异常分为 Error 和 Exception。其中Error一般指与虚拟机相关的错误,如系统崩溃、虚拟机错误、动态链接失败等,应用程序无法处理这些错误;Exception则是指应用程序本身可以处理的异常,它分为Checked Exception和RuntimeException —— Checked异常,也叫编译时异常,Java编译器强制要求我们必须对出现的这种异常进行catch处理,否则程序就不能编译通过;RuntimeException,即运行时异常,编译器不会检查运行时异常,我们也可以不处理,当出现这样的异常时,总是抛出由虚拟机接管。当然运行时异常也是可以catch的。

3. wait(), notify()和notifyAll()在使用的时候需要放在同步方法/代码块中吗?为什么?

【解】需要放在同步方法/同步代码块中,因为这三个方法必须由同步监视器对象来调用。在同步代码块中,同步监视器对象就是 synchronized() 括号中的对象;在同步方法中,同步监视器对象则是隐式的当前对象 this。—— 在调用wait()之前,当前线程已经通过synchronized获得了同步监视器的对象锁,调用了wait()以后,线程进入阻塞状态,并释放对象锁;其他线程获得了同步监视器的对象锁以后,就开始执行它的同步方法/代码块了,在同步方法/代码块中如果调用了notify(),则会唤醒在同步监视器对象上wait的任一线程,等剩余的代码执行完后,释放对象锁;被唤醒的线程尝试获取对象锁,获取到了以后线程继续向下执行。notifyAll()和notify()类似,只不过notifyAll()是唤醒在同步监视器对象上wait的所有线程,这些线程后续会争夺对象锁,谁得到对象锁谁继续执行。

4. 编程:给定两个字符串A,B(只包含26个英文字母),输出所有公共的最长子字符串(如果出现重复子串,则输出多次)

输入包括两行,每行为一个连续字符串(大小写敏感)
输出包括多行,每行为扫描到的最长公共子串,按照该子串在字符串A(即第一行输入字符串)中出现的先后次序输出

样例输入:
abcxyzabcrst
opqrstabc
样例输出:
abc
abc
rst

【解】见文《华为OJ2011-最长公共子串》与最长公共子序列一样,最长公共子串也可以采用动态规划(打表)进行求解。举个例子:X = bab,Y = caba。打表如下:

具体打表的方法是:

  • 第一行、第一列初始化为 0;
  • 对于其他的格子:
    • 若对应的两个字符相等,格子的值设为左上角的值加 1。
    • 若对应的两个字符不相等,直接置 0 。
  1. #include<iostream>  
  2. #include<string>  
  3. #include<vector>  
  4. using namespace std;  
  5.   
  6. int main() {  
  7.     string X, Y;  
  8.     getline(cin, X);  
  9.     getline(cin, Y);  
  10.     int m = X.length();  
  11.     int n = Y.length();  
  12.     vector<vector<int> > table(m+1, vector<int>(n+1));  
  13.   
  14.     int biggest = 0;  // 记录表中的最大值  
  15.     vector<pair<intint> > firstPos;  // 记录子串开始的坐标  
  16.     for(int i=0; i<m+1; ++i)   
  17.     {  
  18.         for(int j=0; j<n+1; ++j)   
  19.         {  
  20.             if(i==0 || j==0)  // 第一行和第一列置0  
  21.                 table[i][j]=0;  
  22.             else if(X[i-1] == Y[j-1])   
  23.             {  
  24.                 table[i][j] = table[i-1][j-1] + 1;  
  25.                 if(table[i][j] > biggest)  
  26.                     biggest = table[i][j];  
  27.                 if(table[i][j] == 1)  
  28.                     firstPos.push_back(make_pair(i, j));  
  29.             }  
  30.             else  
  31.                 table[i][j] = 0;  
  32.         }  
  33.     }  
  34.     // 以下输出所有最长公共子串  
  35.     vector<pair<int,int> >::iterator it = firstPos.begin();  
  36.     for( ; it!=firstPos.end(); ++it)   
  37.     {  
  38.         int startX = it->first-1;  
  39.         int startY = it->second-1;  
  40.         if(X.substr(startX,biggest) == Y.substr(startY,biggest))  
  41.             cout << X.substr(startX, biggest) << endl;  
  42.     }  
  43. }  

5. 编程:在一个整数的数组中删除另外一个整数数组中的元素,并保留原数组的次序
输入包括两行:

1. 第一行是被删除的整数列表(记为列表A),每个整数之间使用空格分隔
2. 第二行是需要删除的整数列表(记为列表B),每个整数之间使用空格分隔

输出只有一行,即列表A中删除列表B元素后的整数列表,输出元素按照在列表A中的次序排列,每个整数之间使用空格分隔

样例输入:
1 2 3 4 5
2 4
样例输出:
1 3 5

【解】本题较简单,获取第一行时,用一个list保存;获取第二行时,将每个数从list中删除,最后输出即可。

  1. #include<iostream>  
  2. #include<list>  
  3. #include<string>  
  4. #include<sstream>  
  5. using namespace std;  
  6.   
  7. int main() {  
  8.     list<int> mylist;  
  9.     for(int i=0; i<2; ++i) {  
  10.         int n;  
  11.         string str;  
  12.         getline(cin, str);  
  13.         stringstream ss(str);  
  14.         while(!ss.eof()) {  
  15.             ss >> n;  
  16.             if(i==0)  
  17.                 mylist.push_back(n);  
  18.             else  
  19.                 mylist.erase(find(mylist.begin(),mylist.end(),n));  
  20.         }  
  21.         ss.clear();  
  22.     }  
  23.   
  24.     list<int>::iterator it = mylist.begin();  
  25.     for( ;it!=mylist.end(); ++it) {  
  26.         cout << *it << " ";  
  27.     }  

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值