- 写在前面,几个月没怎么看过Java,昨天上午突然决定参加一下这个笔试,然后立马投了简历。晚上参加远程笔试,题目不算难,算是普通水平,算法题也没有难到不会写。但我还是把
实现栈
(会写的写错最气人)的那题写错了,交完答案,重新看了一眼题,瞬间就骂自己sb,脑子当时不知道在想什么???这么简单的题,都给写错,怕是没机会参与面试了。不过也好,趁着最后一个月,多投几个简历,复习一下自己几个月没看的Java。最后,吐槽一下,纸上写代码简直是活受罪啊啊啊,强烈推荐算法题还是在线上编程比较好,另外就是我写的字太难看了(我是辣鸡,只会嘤嘤嘤…)。最后,不管结果如何,总结一下至关重要,另外也告诫自己,下一次遇到这种简单的题目就别写错了。在写错,自己就真是个sb了。
简答题
- 写出你用过的linux命令,举例说明其中几个的具体用法。
- mkdir、chomd、apt-get update、ifconfig、vim、cd、…(用法就不说了,不懂的Google)
- 写出TCP的三次握手和四次握手的过程。
- 三次握手:假设 A 为客户端,B 为服务器端。首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。B 收到 A 的确认后,连接建立。
- 四次挥手:假设 A 为客户端,B 为服务器端。首先A 发送连接释放报文,FIN=1。B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。当 B 不再需要连接时,发送连接释放报文,FIN=1。A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(最大报文存活时间)后释放连接。B 收到 A 的确认后释放连接。
- 将一个句子按单词反序。比如 “the sky is blue”,反序后变为 “blue is sky the”?
public static String reverse(String S) {
String[] strs = S.trim().split(" ");
StringBuilder sb = new StringBuilder();
for (int i = strs.length - 1; i >= 0; i--) {
sb.append(strs[i]);
sb.append(" ");
}
return sb.toString().trim();
}
- 一张学生成绩表score,部分内容如下:
name course grade
张三 操作系统 67
张三 数据结构 86
李四 软件工程 89
用一条SQL 语句查询出每门课都大于80 分的学生姓名。
这题这不会写,好久好久没写过SQL语句了,问题这就暴露出来了。看来自己需要好好复习一下SQL语句了。
答案:
select distinct name from score where name not in (select name from score where grade <= 80);
- 接口和抽象类的区别是什么?
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。(JDK 1.8 以后,接口里可以有静态方法和方法体了。)
- 集合类用过哪些,分别列举出来,并指出它们各自使用了那些数据结构。
- ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap、ConcurrentHashMap…
- Spring的IOC和AOP是什么? Spring有哪些优点?谈谈你对spring的理解。
- IOC:控制反转(Inversion of Control),即创建被调用者的实例不是由调用者完成,而是由 Spring 容器完成,并注入调用者。
- AOP:面向切面,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能,降低代码的耦合度。
编程题
- 实现一个栈,包含栈的基本操作(pop、push、top、size)。
public class Stack {
Queue<Integer> in;
Queue<Integer> out;
public Stack() {
in = new LinkedList<>();
out = new LinkedList<>();
}
public int pop() {
return out.poll();
}
public void push(int x) {
in.add(x);
while (!out.isEmpty()) {
in.add(out.poll());
}
Queue tmp = in;
in = out;
out = tmp;
}
public int top() {
return out.peek();
}
public int size() {
return (in.size()+out.size());
}
}
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<Integer>();
}
public void push(int x) {
int n = queue.size();
queue.offer(x);
for (int i = 0; i < n; i++) {
queue.offer(queue.poll());
}
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
public int size() {
return queue.size();
}
}
// 用数组实现栈,缺点是数组的大小已经固定。因此栈的最大容量也已经确定。
class Stack {
int[] stack;
int i;
public Stack() {
stack = new int[1000];
i = 0;
}
public void push(int x) {
stack[i++] = x;
}
public int pop() {
return stack[i--];
}
public int top() {
return stack[i];
}
public int size() {
return i+1;
}
}
- 给定一个无序数组arr,找到数组中未出现的最小正整数
例如arr = [-1, 2, -3, 4]。返回1
arr = [1, 2, 3, 4]。返回5
[要求]
时间复杂度尽可能的低。
public static int minInt(int[] arr) {
int len = arr.length;
for (int i = 0; i < len; i++){
if (arr[i] > 0 && arr[i] < len) {
int tmp = arr[arr[i]-1];
arr[arr[i]-1] = arr[i];
arr[i] = tmp;
}
}
for (int i = 0;i < len; i++) {
if (arr[i] != i+1) {
return i+1;
}
}
return len+1;
}
你知道的越多,你不知道的越多。