近期面试题集
太多了,就先这样吧。。。。。加油,继续更。
1、代码写完之后,如何上传到服务器上,大致流程。
在服务器上安装类似Tomcat安装容器,然后在容器中配置加载项目,或者
将项目复制到webapp目录,将数据库安装好,配置好,接着启动容器,看有没有异常,
如果没有异常,就用http协议访问域名。
2、Git命令
git init 本地初始化
git status 查看工作区,暂存区的状态
git commit 提交
git add 添加
git reset 基于索引值得操作
3、Git的分支
hot fix(热修复)
master(主干)
feature_blue
feature_game
分支命令:
git branch -v 查看本地库中所有分支
git branch dev 创建一个新的分支
git存入k/V数据库,而svn是按照文件的方式进行一个存储的
4、linux命令,查看进程
查看进程ps命令,然后通过管道grep命令查找特定的进程,然后再对特定的进程进行操作
杀进程:kill 可以直接使用进程名字
修改权限:chmod
磁盘空间 :df
查看自己的IP地址:ifconfig
5、Linux免密登录
假设2台服务器:1台Master 1台Slave
Master作为一个客户端,实现无密码公钥认证,会生成一个公钥和一个私钥,公钥
会复制到所有的Slave上。
Slave会生成一个随机数,用Master公钥对随机数进行加密。
重要的是将客户端Master的公钥复制到Slave上。
6、OSI模型简化为(传输层)TCP和(网络层)IP模型
三次握手,四次挥手
7、poi基本步骤:
1、用HSSFWorkbook打开或者创建“Excel文件对象”
2、用HSSFWorkbook对象返回或者创建Sheet对象
3、用Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象读写。
8、== 和 equals 的区别是什么?
== 解读
对于基本类型和引用类型 == 的作用效果是不同的,如下所示:
- 基本类型:比较的是值是否相同;
- 引用类型:比较的是引用是否相同;
代码示例:
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
代码解读:因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而 new String()方法则重写开辟了内存空间,所以 == 结果为 false,而 equals 比较的一直是值,所以结果都为 true。
equals 解读
equals 本质上就是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。看下面的代码就明白了。
首先来看默认情况下 equals 比较一个有相同值的对象,代码如下:
class Cat {
public Cat(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Cat c1 = new Cat("王磊");
Cat c2 = new Cat("王磊");
System.out.println(c1.equals(c2)); // false
输出结果出乎我们的意料,竟然是 false?这是怎么回事,看了 equals 源码就知道了,源码如下:
public boolean equals(Object obj) {
return (this == obj);
}
原来 equals 本质上就是 ==。
那问题来了,两个相同值的 String 对象,为什么返回的是 true?代码如下:
String s1 = new String("老王");
String s2 = new String("老王");
System.out.println(s1.equals(s2)); // true
同样的,当我们进入 String 的 equals 方法,找到了答案,代码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
原来是 String 重写了 Object 的 equals 方法,把引用比较改成了值比较。
总结 :== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。
9、final 在 Java 中有什么作用?
- final 修饰的类叫最终类,该类不能被继承。
- final 修饰的方法不能被重写。
- final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
10、String 类的常用方法都有那些?
- indexOf():返回指定字符的索引。
- charAt():返回指定索引处的字符。
- replace():字符串替换。
- trim():去除字符串两端空白。
- split():分割字符串,返回一个分割后的字符串数组。
- getBytes():返回字符串的 byte 类型数组。
- length():返回字符串长度。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- substring():截取字符串。
- equals():字符串比较。
11、接口和抽象类有什么区别?
- 实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
- 构造函数:抽象类可以有构造函数;接口不能有。
- 实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
- 访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。
12、ArrayList 和 LinkedList 的区别是什么?
- 数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
- 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。
- 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。
综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。
13、创建线程有哪几种方式?
创建线程有三种方式:
- 继承 Thread 重写 run 方法;
- 实现 Runnable 接口;
- 实现 Callable 接口。
14、39.说一下 runnable 和 callable 有什么区别?
runnable 没有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的补充。
15、线程有哪些状态?
线程的状态:
- NEW 尚未启动
- RUNNABLE 正在执行中
- BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
- WAITING 永久等待状态
- TIMED_WAITING 等待指定的时间重新被唤醒的状态
- TERMINATED 执行完成
16、sleep() 和 wait() 有什么区别?
- 类的不同:sleep() 来自 Thread,wait() 来自 Object。
- 释放锁:sleep() 不释放锁;wait() 释放锁。
- 用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。
17、线程池都有哪些状态?
- RUNNING:这是最正常的状态,接受新的任务,处理等待队列中的任务。
- SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务。
- STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。
- TIDYING:所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()。
- TERMINATED:terminated()方法结束后,线程池的状态就会变成这个。
18、什么是死锁?
当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。
19、怎么防止死锁?
- 尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。
- 尽量使用 Java. util. concurrent 并发类代替自己手写锁。
- 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
- 尽量减少同步的代码块。
20、动态代理是什么?有哪些应用?
动态代理是运行时动态生成代理类。
动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java注解对象获取等。
21、怎么实现动态代理?
JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。
22、如何避免 SQL 注入?
- 使用预处理 PreparedStatement。
- 使用正则表达式过滤掉字符中的特殊字符。
23、#{} 和 ${} 的区别是什么?
- #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。$将传入的数据直接显示生成在sql中。
- #方式能够很大程度防止sql注入,$方式无法防止Sql注入。
- mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
- Mybatis在处理 时 , 就 是 把 {} 时,就是把 时,就是把{}替换成变量的值,直接进行sql拼接。
- 使用#{}可以有效的防止SQL注入,提高系统安全性。
24、介绍 MyBatis 的一级缓存和二级缓存的概念和实现原理?
1.一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
2.二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置
3.对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
25、你了解的Mysql的几种引擎? 分别适合什么样的数据库
MyISAM(默认引擎):查询性能高,并发修改数据性能低、不支持外键、不支持事务。
INNODB:修改数据性能高,支持事务,支持外键、查询性能相对MyISAM要低;
MEMORY: 所有的数据都在内存中,数据的处理速度快,但是安全性不高。
分别适用?
MyISAM:如果这个数据库中查询要求比较高可以选择MyISAM存储,因为其特性在做数据库读写分离时通常会把读取的表的存储引擎设置为MyISAM。
INNODB:如果需要比较高的事务处理,高并发写的业务场景,可以选择InnoDB。
MEMORY:如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎。
26、mysql的性能优化方式有哪些,你用过哪几种,分别在什么情况下去使用的
1、避免 SELECT *,需要什么数据,就查询对应的字段。
2、利用自增主键索引、order by
加limit
,不使用offset
3、在性能要求比较高的场景中,杜绝查询中使用临时表
4、使用 EXPLAIN 关键字分析SQL语句性能。