(此系列试题来源于Java面试宝典书籍)
一、选择题
1. ArrayList list = new ArrayList(20);语句中的 list 集合大小扩充了几次
首先初始化化10个空间,当10个满了之后再插入才是扩充
2. 如果去掉main方法的static修饰符会怎样
- A. 程序无法编译
- B. 程序能正常编译,运行时或抛出NoSuchMethodError异常
- C. 程序能正常编译,正常运行
- D. 程序正常编译,正常运行一会会立刻退出
3. 启动java程序进程时,输入一下哪个参数可以实现年轻代的堆大小为50M
- A. -Xms50M
- B. -Xmx50M
- C. -Xmn50M
- D. -Xss50M
解析:https://www.cnblogs.com/qlqwjy/p/8037797.html 作者:Qiao_Zhi
- -Xms:初始化堆大小
- -Xmx:最大堆大小
- -Xmn:年轻代大小
- -Xss:每个线程的堆栈大小
4.
public class Test5 {
public static boolean fo(char c){
System.out.print(c);
return true;
}
public static void main(String[] args) {
int i = 0;
for (fo('A');fo('B') & (i < 2);fo('C')){
i++;
fo('D');
}
// result:ABDCBDCB
// 这个其实就是for里的判断顺序
}
}
5. 输出结果
System.out.println(Integer.MAX_VALUE * 2);
System.out.println(Integer.MIN_VALUE * 2);
//result:-2 0
解析:
1) 无符号和有符号,
- 无符号数中,所有的位都用于直接表示该值的大小
- 有符号数中最高位用于表示正负,所以,当为正值时,该数的最大值就会变小
- 例:无符号数: 1111 1111 --> 255 有符号数: 0111 1111 --> 127
- 无符号数: 0 ----------------- 255 有符号数: -128 --------- 0 ---------- 127
- java没有无符号类型,都是有符号类型的数据类型
2)
6. log4j的优先级从高到低的排序
- A. error>warn>info>debug
7. 下列关于 Thread 类提供的线程控制的方法中,错误的一项是
- A. 在线程A中执行线程B的join()方法,则线程A等待直到B执行完成
- B. 线程A通过调用interrupt()方法来中断其阻塞状态
- C. currentThread()方法返回当前线程的引用
- D. 若线程A调用isAlive()返回true,则说明A正在执行中
解析:这道题有问题,全对
t.join()方法阻塞调用此方法的线程(calling thread)进入 TIMED_WAITING 状态,直到线程t完成,此线程再继续
A线程中调用B线程的join方法的时候,先获取当前B线程对象的锁,然后判断B线程是否存活,如果B存活则调用wait方法等待,A线程进入超时等待状态,A线程释放锁,直到B线程结束才继续运行
8. String a = new String("1"+"2")最终创建了几个对象
- A. 1
- B. 2
- C. 3
- D. 4
解析:"1"+"2"最终优化为1个对象,new一个对象,一共2个对象
https://blog.youkuaiyun.com/yishao_20140413/article/details/23598113 作者:逸卿
9. 下列哪一条语句可以实现快速的复制一张数据库表:insert into b as select * from a where 1<>1
10. 属于单例模式的特点
- A. 提供了对唯一实现的受控空间
- C. 单例模式的抽象层会导致单例类扩展的困难
- D. 单例模式很容易导致数据库的连接池溢出
11. 选择Oracle的分页语句的关键字:rownum
Mysql:limit
12. 查询所有的表和视图的方法
- A. preparedStatement.getMetaData().getTables(***);
- B. connection.getMetaData().getTables(***);
- C. result.getMetaData().getTables(***);
- D. DiverManager.getMeta().getTables(***);
13. MySQL 用 truncate 命令快速清空一个数据库中的所有表
14. 文件对外共享的协议有哪几个
- A. FTP
- B. Windows共享
- C. TCP
- D. SSH
15. 以下哪些不属于约束
- A. 主键
- B. 外键
- C. 索引
- D. 唯一索引
- E. not null
16. 下列关于数据库连接池的说法中哪个是错误的
D. 当使用池连接调用完成后,池驱动程序将此连接标记为空间,其他调用就可以使用这个连接
17. 以下哪句是对索引的错误描述
C. 过多的索引只会阻碍性能的提升,而不是加速性能
18. 关于锁 locks,描述正确的是
A. 当一个事务在表上防止了共享锁(shared lock),其他事务,能阅读表里的数据
19. 如下那种情况下,Oracle 不会使用 Full Table Scean(D)
D. 本次查询可以用到该张表的一个引用,但是该表具有多个索引包含用于过滤的字段
二、问答题
1. 如何判断两个单项链表相交,如何找到交点
- 直接法:采用暴力的方法,遍历两个链表,判断第一个链表的每个结点是否在第二个链表中,时间复杂度为
O(len1*len2),耗时很大
-
hash计数法:如果两个链表相交,则两个链表就会有共同的结点;而结点地址又是结点唯一标识。因而判断两个链表中是否存在地址一致的节点,就可以知道是否相交了
-
先遍历第一个链表到他的尾部,然后将尾部的 next 指针指向第二个链表(尾部指针的 next 本来指向的是 null)。这样两个链表就合成了一个链表,判断原来的两个链表是否相交也就转变成了判断新的链表是否有环的问题了:即判断单链表是否有环
-
仔细研究两个链表,如果他们相交的话,那么他们最后的一个节点一定是相同的,否则是不相交的
2. 如何从cookie中拿到session
session 在服务器端,cookie 在客户端(浏览器),session 默认被存在在服务器的一个文件里(不是内存),session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁 用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id); session 可以放在 文件、数据库、或内存中都可以
3. 打印下面两个数组的交集,结果不能重复
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test6 {
public static String[] IOU(String[] arr1,String[] arr2){
List<Integer> list = new ArrayList<>();
for (int i=0;i<arr1.length;i++){
for (int j=0;j<arr2.length;j++){
if (arr1[i].equals(arr2[j])){
list.add(i);
}
}
}
String[] result = new String[list.size()];
int i = 0;
for (int index: list) {
result[i] = arr1[index];
i++;
}
return result;
}
public static void main(String[] args) {
String[] arr1 = {"112","wqw","2121"};
String[] arr2 = {"112","aad","ewqw"};
String[] result = IOU(arr1,arr2);
System.out.println(Arrays.toString(result));
}
}
4. SpringMvc 拦截器用过吗?什么场景会用到,过滤器,拦截器,监听器有什么区别?
1) Interceptor
- 拦截器是指通过统一拦截从浏览器发往服务器的请求来完成功能的增强
- 使用场景:解决请求的共性问题(乱码问题、权限验证问题)
拦截器是在面向切面编程中应用的,就是在你的 service 或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于 JAVA 的反射机制。拦截器不是在 web.xml
2) Filter
Servlet 中的过滤器 Filter 是实现了 javax.servlet.Filter 接口的服务器端程序,主要的用途是过滤字符编码、 做一些业务逻辑判断等。其工作原理是,只要你在 web.xml 文件配置好要拦截的客户端请求,它都会帮你拦截到 请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用 户是否已经登陆、有没有权限访问该页面等等工作。它是随你的 web 应用启动而启动的,只初始化一次,以后就 可以拦截相关请求,只有当你的 web 应用停止或重新部署的时候才销毁
3) Listener
现在来说说 Servlet 的监听器 Listener,它是实现了 javax.servlet.ServletContextListener 接口的服务器端 程序,它也是随 web 应用的启动而启动,只初始化一次,随 web 应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等
5. ThreadLocal的原理和应用场景
- 每一个 ThreadLocal 能够放一个线程级别的变量,可是它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全
- 最常见的 ThreadLocal 使用场景为 用来解决数据库连接、Session 管理等
6. TCP三次握手
-
第一次握手:建立连接时,客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)
-
第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态
-
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1), 此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手 客户端与服务器开始传送数据
7. SprinMVC request接受设置是线程安全的吗
是线程安全的,request、response 以及 requestcontext 在使用时不需要进行同步。而 根据 spring 的默认规则,controller 对于 beanfactory 而言是单例的。即 controller 只有一个, controller 中的 request 等实例对象也只有一个
8. Maven常见的六种依赖范围
-
compile:编译依赖范围(默认),对其三种都有效
-
test:测试依赖范围,只对测试 classpath 有效
-
runtime:运行依赖范围,只对测试和运行有效,编译主代码无效,例如 JDBC
-
provided:已提供依赖范围,只对编译和测试有效,运行时无效,例如 selvet-api
-
system:系统依赖范围.谨慎使用.例如本地的,maven 仓库之外的类库文件
-
import(maven2.0.9 以上):导入依赖范围,不会对其他三种有影响
9. Mybatis如何防止sql注入,mybatis拦截器,应用场景是什么
-
Mybatis 使用#{}经过预编译的,是安全的,防止 sql 注入
-
Mybatis 拦截器只能拦截四种类型的接口:Executor、StatementHandler、ParameterHandler 和 ResultSetHandler。这是在 Mybatis 的 Configuration 中写死了的,如果要支持 拦截其他接口就需要我们重写 Mybatis 的 Configuration。Mybatis 可以对这四个接口中所有的方法进行拦截。Mybatis 拦截器常常会被用来进行分页处理。
10. 自动装配模式
- no
- byName
- byType
- constructor
- autodetect
11. 假设有50瓶饮料,喝完三个空瓶换一瓶饮料
public class NumDrinkl {
public static void Drink(int n){
int i=0; //兑换次数
while(true) {
n -= 3; //喝 3 瓶
n++; //兑换 1 瓶
i++; //兑换次数+1
if (n < 3) {
System.out.println("共喝了" + (50 + i) + "瓶");
break;
}
}
}
public static void main(String[] args) {
int drinkN = 50;
Drink(drinkN);
}
}
12. 给出年月日,编程得到是当年的第几天
import java.util.Scanner;
public class Test7 {
public static void main(String[] args) {
// 存储结果
int result = 0;
Scanner s = new Scanner(System.in);
System.out.println("请输入年份:");
int year = s.nextInt();
System.out.println("请输入月份:");
int month = s.nextInt();
System.out.println("请输入号:");
int day = s.nextInt();
// 月份天数
int[] days = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
// 判断年份 能被4整除且不能被100整除
for (int i=0;i<month-1;i++){
if((year % 4 ==0) & (year % 100 != 0)) {
// 判断月份
if (i == 1) {
result += days[i] + 1;
}
}else {
result += days[i];
}
}
// 当前月份的天数
result = result + day;
System.out.println("今天是该年的第"+result+"天");
}
}
13. 利润与奖金编程
14. 单例模式
- 懒汉式
- 饿汉式
15. 乐观锁和悲观锁
16. log4j的配置中%t表示什么