当前位置: 移动互联网学院 > Java培训 > JAVA面试题 > 人人网java面试题 实操
人人网java面试题 实操 时间:2017-12-14     来源:java面试宝典

进了公司之后,看到里面已经来了好几个来面试的人,递交简历之后被安排到一台笔记本面前,总共有五道题目,不准百度,不能交头接耳。他们有一套自己的评分方式,有自己的输入输入用例,有点像OJ题目,限时30分钟。判分60分以上就能进入面试,不及格就不能进入面试,只好走人。

五道题分别如下:

1.结合金融业务,实现转账过程,从账户A转到账户B,注意金额不能为负数。

public class User{

private String name;

private int blance;

//getter/setter方法

}123456

这道题要做的几现实它的一个计算方法,上面提供了JavaBean,题目代码貌似如下:

/**

*

* @param blanceFrom 借贷人

* @param blanceTo 借款人

* @param blance 借款金额

*/

public static void execute(User blanceFrom, User blanceTo, int blance) {

}

12345678910

这道题不难,需要注意的是判断空指针异常和blance非负数,所以这里我就不提供参考代码了。

2.回文数问题。我感觉这道题描述有问题,按照我的理解是写一算法判断是否为回文数。但是题目却说比如1221,1234321等都不是回文数,我一脸蒙逼,问面试官是不是题目描述错误了。面试官十分肯定的回答我:题目没有错,会做就做,不会做的可以跳过。

本题我直接跳过,不过我解题思路是先把原字数赋值到新的变量,不断的对原来的数字对10取余,然后数字本身除以10,直到该数为0为止。

public boolean isHuiWen(int number) {

int oldNumber = number;

int newNumber = 0;

while(number != 0) {

newNumber = newNumber*10 + number%10;

number /= 10;

}

if(oldNumber == newNumber) {

return true;

}

return false;

}12345678910111213

3.统计句子中每个单词出现的次数。比如如下句子中

Java this is a Java Hello World Thank you

本句子中,各单词出现次数如下:

“Java”出现2次

“this”出现1次

“is”出现1次

“a”出现1次

“Hello”出现1次

“World”出现1次

“Thank”出现1次

“you”出现1次

空格不进入统计里边。这道题用Map的数据结构来做适合,Map是一种key-value的数据结构。首先用正则表达式将句子切割成String数组,然后遍历这个数组把第i个元素的值作为Map的key,出现次数作为value,当第一次存入key时value等于1,否则value+1。

public Map wordCount(String sentence) {

String[] strs = sentence.split("\\s+");

Map wordMap = new HashMap();

for(int i = 0; i < strs.length; i++) {

if(wordMap.get(strs[i]) == null) {

wordMap.put(strs[i], 1);

} else {

wordMap.put(strs[i], wordMap.get(strs[i])+1);

}

}

return wordMap;

}12345678910111213

4.将阿拉伯字母转为汉字。比如123转为一百二十三。

二面的面试题目

【填空题】

java面向对象的三大特征是:_______,_______,_______.

答:封装,继承,多态。

sleep()和wait()的区别是___________________________.

答:(1)sleep()不释放对象锁,wait()释放对象锁。

(2)sleep()可以在时间未到时被打断,抛出异常,所以需要捕获异常,wait不需要捕获异常。

(3)sleep()是Thread类的方法,wait()是Object类的方法。

一个类被JVM回收的标志是_______________________.

答:类未被其他的活动类引用。

重写JAVA equals方法,需要同时重写:_____________.

答:hashCode方法。这是JAVA的常规约定,如果不重写hashCode,使用HashMap,HashSet等类时会出现错误。调用equals()方法比较两个对象的时候,编译器会自动调用hashCode()来比较两个对象是否产生相同的整数结果.equals()返回true,则hashCode()必返回true.equals()返回false,则hashCode()必返回false.那么重写equals()方法,肯定必须重写hashCode方法来保证二者的同步.

String, StringBuilder, StringBuffer的区别:____________.

答:String保存字符串常量,字符串的每次变化都会产生一个新的字符串对象。StringBuilder和StringBuffer都是可以变化而不产生新的对象的。其中,StringBuffer是线程安全的,StringBuilder是线程不安全的。

增加数据表一列的SQL语法:_____________________.

答:alter [table] add [列].

JSP的内置对象及方法request,_______,______,_______.(常用三个即可)

答:response,session,out,page,application,exception,pageContext,config.

List,Set,Map是否继承自Collection接口:_____________.

答:List和Set 是的,Map不是。

数据库事务特征________,________,________,________.

答:ACID,原子性,一致性,隔离性,持久性。

针对10,100,32,45,58,126,3,29,200,400,0利用除商留余法构造长度为13的数据的HASH:________________________________.

答:全部除以25再取余数,再连到一起?结果是:1007208134000.也可能后再MOD一个10000000000000,题意没有读懂。

【选择题】

已知:

Integer i=new Integer(42);

Long l=new Long(42);

Double d=new Double(42.0);

下面哪些选项返回结果为true:

A.(i==l)

B.(i==d)

C.(d==l)

D.(i.equals(d))

E.(d.equals(l))

F.(i.equals(l))

G.(l.equals(42L))

答:ABC显然是错的,==比较的是两个对象的地址。Long 和 Double之间,Integer 和 Double之间都是不能自动转化的。但是Long和Integer之间可以自动转化,所以,F和G是正确的。

关于用abstract定义的类,下列说法正确的是()

可以被实例化 B.不能够派生子类 C.不能被继承 D.只能被继承 E.能够被抽象类继承

答:概念题,DE是正确的。

当线程A使用某个对象,而此对象又需要线程B修改后才能符合A线程的需要,这时线程A就要等待线程B完成修改工作,这种现象称为()

线程的同步 B.线程的互斥 C.线程的调度 D.线程的就绪

答:概念题,C。

在JAVA程序中定义一个类,类中有一个没有访问权限修饰的方法,则此方法()

A. 类外的任何方法都能访问它

B. 类外的任何方法都不能访问它

C. 类的子类和同包类能访问它

D. 只有类和同包类才能访问它

答:概念题,D。

有如下程序代码,在执行完后x和y的值是多少()

Int x=8,y=2,z;

x=++x*y;

z=x/y++;

x=16,y=2.

X=16,y=4.

X=18,y=2.

X=18,y=3.

答:D,不解释。

【问答题】

int i=0;i=i++;以上操作中i=i++;是线程安全的吗?如果不安全请说明上面操作在JVM中执行过程,为什么不安全?并且说出JDK中哪个类能达到以上程序的效果,并且是线程安全而且高效,并简述其原理。

答:不是线程安全的。JVM中,赋值语句的执行过程是,先把赋值号右边的值存入一个栈中,再从栈中弹出到赋值号左边的变量中。所以,在执行i=i++后i的值为0。但是如果在多线程的环境下执行i=i++,线程A中执行到把i压入栈,而在此之前线程B中执行到把i++,那么栈中i的值就已经改变了,后线程A执行弹栈的操作,那么i的值就不是0了,所以是线程不安全的。AtomicInteger中提供了线程安全且高效的原子操作。其底层的原理是利用处理器的CAS(比较并交换)操作来检测栈中的值是否被其他线程改变,如果被改变则CAS操作失败。这种实现方法比用sycronized来实现同步,底层显然有着更高的执行效率。

2.数组int[n] a={1,2,2,……}数组a满足以下条件,均为正整数,a[i+1]>=a[i]快速找出满足a[i]=i的数。

答:这道题大家都没有想出O(logn)的算法,只好从常数上优化。可以看出的一个性质是数组下标每次都是固定地增加1,所以若a[i]>i,则接下来的a[i]-i-1个数一定不可能满足a[i]=i;如果a[i]

package com.test;

import java.util.Scanner;

public class Main1 {

private static Integer[] a = new Integer[500];

private static String[] str;

public static int find(int l, int r) {

if (l > r)

return -1;

if (a[l] == l)

return l;

if (a[r] == r)

return r;

int left_increment = Math.abs(a[l] - l);

int right_increment = Math.abs(a[r] - r);

return find(l + left_increment, r - right_increment);

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String string = scanner.nextLine();

str = string.split(" ");

for (int i = 0; i < str.length; i++)

a[i] = Integer.parseInt(str[i]);

int pos = find(0, str.length - 1);

if (pos == -1)

System.out.println("不存在满足a[i]==i的数");

else

System.out.println("找到满足条件的数:a[" + pos + "]==" + pos);

}

}

3.数组 int[n] a={1,2,3,3,4,3,2……}数组a中的数均为正整数,求满足a[i]+a[t]=a[x],其中i,t,x均为正数,且小于等于n,求大a[x].

答:本人水平有限,目前只想到O(n^2*logn)时间复杂度的算法。先将数组排序,然后从后往前枚举a[x],对于每一个a[x],从0到a[x-1],枚举a[i]的值,再二分查找a[t]是否存在,代码如下:

package com.test;

import java.util.Scanner;

public class Main1 {

private static Integer[] a = new Integer[500];

private static String[] str;

public static void quicksort(int l, int r) {

if (l >= r)

return;

int i = l - 1, j = r + 1;

int mid = a[(l + r) >> 1];

while (i < j) {

i++;

j--;

while (a[i] < mid)

i++;

while (a[j] > mid)

j--;

if (i < j) {

int t = a[i];

a[i] = a[j];

a[j] = t;

}

}

quicksort(l, j);

quicksort(j + 1, r);

}

public static boolean fen_2(int t) {

int l = 0, r = str.length - 1, mid;

while (l < r) {

mid = (l + r) >> 1;

if (a[mid] == t)

return true;

if (a[mid] < t)

l = mid + 1;

if (a[mid] > t)

r = mid;

}

return false;

}

public static int find() {

for (int i = str.length - 1; i >= 0; i--) {

for (int j = 0; j < i; j++)

if (fen_2(a[i] - a[j]))

return i;

}

return -1;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String string = scanner.nextLine();

str = string.split(" ");

for (int i = 0; i < str.length; i++)

a[i] = Integer.parseInt(str[i]);

quicksort(0, str.length - 1);

int ff = find();

if (ff != -1)

System.out.println("大的a[x]为:" + a[ff]);

else

System.out.println("没有在数组中找到满足条件的数");

}

}

我的朋友廖宇翔大神说了一个O(n^2)的算法,之前我也想到了,但是我误认为这是一个错误的算法,会出现某些状态没有枚举到的情况,不过在大神的开导下我豁然开朗。仍然是先快速排序,从后向前枚举a[x],然后设定两个指针p,q分别指向a[0]和a[x-1],从两边往中间扫,如果两个指针指向的数相加大于a[x],则q指针向左移(若存在a[i]和a[t]满足条件,那么此时i和t必然在数组下标为0到x-2的区间内);如果个指针指向的数相加小于a[x],则p指针向右移(同理)。

代码如下:

package com.test;

import java.util.Scanner;

public class Main1 {

private static Integer[] a = new Integer[500];

private static String[] str;

public static void quicksort(int l, int r) {

if (l >= r)

return;

int i = l - 1, j = r + 1;

int mid = a[(l + r) >> 1];

while (i < j) {

i++;

j--;

while (a[i] < mid)

i++;

while (a[j] > mid)

j--;

if (i < j) {

int t = a[i];

a[i] = a[j];

a[j] = t;

}

}

quicksort(l, j);

quicksort(j + 1, r);

}

public static int find() {

for (int i = str.length - 1; i >= 0; i--) {

int p = 0, q = i - 1;

while (p <= q) {

if (a[p] + a[q] > a[i]) {

q--;

continue;

}

if (a[p] + a[q] < a[i]) {

p++;

continue;

}

return i;

}

}

return -1;

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String string = scanner.nextLine();

str = string.split(" ");

for (int i = 0; i < str.length; i++)

a[i] = Integer.parseInt(str[i]);

quicksort(0, str.length - 1);

int ff = find();

if (ff != -1)

System.out.println("大的a[x]为:" + a[ff]);

else

System.out.println("没有在数组中找到满足条件的数");

}

}

4.用JAVA扫描指定文件夹下面所有以.txt,.log结尾的文件,并将其绝对路径输出。

答:主要考察递归遍历文件夹以及获取文件后缀名两部分。

简要介绍一下你所熟悉的设计模式,并给自己假设一种应用场景,并用程序将其实现,并指出如此设计的优缺点(单实例模式除外)

答:proxy模式,意图为其他对象提供一种代理以控制对这个对象的访问。优点: 向客户端隐藏了访问某个对象的细节及复杂性;可以动态地调用一个对象中的方法,且无需实现固定的接口。在AOP编程中,可以利用proxy模式来实现核心代码和日志代码的分离。程序实现如下:

InterfaceCore接口:

package com.test.interceptor;

public interface InterfaceTarget {

public void docore();

}

core类:

package com.test.interceptor;

public class Target implements InterfaceTarget {

public void docore() {

System.out.println("核心代码:我现在非常无聊!");

}

}

MyLogger类:

package com.test.interceptor;

public class MyLogger {

public void before(){

System.out.println("无聊之前记一下");

}

public void after(){

System.out.println("无聊之后又记一下");

}

}

MyProxy类:

package com.test.interceptor;

import java.lang.reflect.Proxy;

public class MyProxy {

public Object getProxy(Object object){

MyHandler myhandler=new MyHandler(object);

return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), myhandler);

}

}

MyHandler类:

package com.test.interceptor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class MyHandler implements InvocationHandler{

private Object object;

private MyLogger logger = new MyLogger();

public MyHandler(Object object){

this.object=object;

}

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

Object result = null;

logger.before();

result = method.invoke(object, args);

logger.after();

return result;

}

}

Client类:

package com.test.interceptor;

public class Client {

public static void main(String args[]){

InterfaceCore core=new Core();

MyProxy myproxy=new MyProxy();

InterfaceCore proxy = (InterfaceCore)myproxy.getProxy(core);

proxy.docore();

}

}

output:

X