持续收集中。。。。。
1基础篇
1.1 spring Bean 生命周期
Spring Bean的生命周期只有这四个阶段。把这四个阶段和每个阶段对应的扩展点糅合在一起虽然没有问题,但是这样非常凌乱,难以记忆。要彻底搞清楚Spring的生命周期,首先要把这四个阶段牢牢记住。实例化和属性赋值对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。
实例化 Instantiation
属性赋值 Populate
初始化 Initialization
销毁 Destruction
实例化 -> 属性赋值 -> 初始化 -> 销毁]
1.2
关于面试题
public class TestClasss {
String sss;
char[] cc;
public static void main(String[] args) {
TestClasss oo = new TestClasss();
oo.sss ="121";
oo.cc = new char[]{'r','3','g'};
//System.out.println(55-total);
oo.getSSS(oo.sss, oo.cc);
System.out.println(oo.sss);
System.out.println(oo.cc的值;
}
public void getSSS(String ss ,char[] cc){
ss="1212";
cc[0]='q';
}
}
oo.sss 值为 121 ,cc的值为 q3g
1.3关于eruka 的原理问答
处于不同节点的eureka通过Replicate进行数据同步
- Application Service为服务提供者
- Application Client为服务消费者
- Make Remote Call完成一次服务调用
服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka
Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。当服务注册中心Eureka
Server检测到服务提供者因为宕机、网络原因不可用时,则在服务注册中心将服务置为DOWN状态,并把当前服务提供者状态向订阅者发布,订阅过的服务消费者更新本地缓存。服务提供者在启动后,周期性(默认30秒)向Eureka Server发送心跳,以证明当前服务是可用状态。Eureka
Server在一定的时间(默认90秒)未收到客户端的心跳,则认为服务宕机,注销该实例。
1.4 == 与equals 区别
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
1.5为什么String定义为final。
1.为了实现字符串池
只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现,因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。2.为了线程安全 因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
3.为了实现String可以创建HashCode不可变性 因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
1.6描述下java集合,项目中用到哪些。
1.7StringBuilder和StringBuffer的区别。
1、java.lang.String 2、java.lang.StringBuffer 3、java.lang.StrungBuilder
三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。StringBuffer是线程安全,可以不需要额外的同步用于多线程中;
StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;
StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。
String实现了三个接口:Serializable、Comparable、CarSequence
StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。
HashMap中常用的方法有哪些,什么时候会触发树化,jdk1.7和1.8实现的差异,1.7的实现为什么会出现死锁,画图说明下。HashMap和TreeMap的区别。
1.8说下枚举类型,底层实现原理,项目中是如何使用的。
枚举本质上是通过普通的类来实现的,只是编译器为我们进行了处理。每个枚举类型都继承自java.lang.Enum,并自动添加了values和valueOf方法。而每个枚举常量是一个静态常量字段,使用内部类实现,该内部类继承了枚举类。所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化。另外通过把clone、readObject、writeObject这三个方法定义为final的,同时实现是抛出相应的异常。这样保证了每个枚举类型及枚举常量都是不可变的。可以利用枚举的这两个特性来实现线程安全的单例
1.9详细描述Error和Exception(运行期和编译期)的区别。
创建线程的方式,线程的生命周期。
https://blog.csdn.net/weixin_36759405/article/details/82843399
ThrealLocal实现原理,为什么会出现内存泄漏。
https://blog.csdn.net/lululove19870526/article/details/83688863
volatile关键字原理,项目中是如何使用的。
https://www.cnblogs.com/shan1393/p/8999683.html
1.10synchronized和lock的区别,底层实现原理。
1、Lock是java的一个interface接口,而synchronized是Java中的关键字,synchronized是由JDK实现的,不需要程序员编写代码去控制加锁和释放;Lock的接口如下:
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition(); } 2、synchronized修饰的代码在执行异常时,jdk会自动释放线程占有的锁,不需要程序员去控制释放锁,因此不会导致死锁现象发生;但是,当Lock发生异常时,如果程序没有通过unLock()去释放锁,则很可能造成死锁现象,因此Lock一般都是在finally块中释放锁;格式如下:Lock lock = new LockImpl; // new 一个Lock的实现类 lock.lock(); // 加锁 try{
//todo }catch(Exception ex){
// todo }finally{
lock.unlock(); //释放锁 } 3、Lock可以让等待锁的线程响应中断处理,如tryLock(long time, TimeUnit
unit),而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够中断,程序员无法控制;
4、synchronized是非公平锁,Lock可以设置是否公平锁,默认是非公平锁;
5、Lock的实现类ReentrantReadWriteLock提供了readLock()和writeLock()用来获取读锁和写锁的两个方法,这样多个线程可以进行同时读操作;
6、Lock锁的范围有局限性,仅适用于代码块范围,而synchronized可以锁住代码块、对象实例、类;
7、Lock可以绑定条件,实现分组唤醒需要的线程;synchronized要么随机唤醒一个,要么唤醒全部线程。
1.11AQS队列实现原理,用了哪些设计模式。
https://www.jianshu.com/p/95a0a02d2655
1.12公平锁和非公平锁、独占锁和共享锁、读写锁分别是如何实现的,为什么说非公平锁比公平锁性能高。
公平锁要维护一个队列,后来的线程要加锁,即使锁空闲,也要先检查有没有其他线程在 wait,如果有自己要挂起,加到队列后面,然后唤醒队列最前面的线程。这种情况下相比较非公平锁多了一次挂起和唤醒
1.13序列化和反序列化。
https://www.cnblogs.com/sinceret/p/10285807.html
1.14深拷贝和浅拷贝区别。
https://www.jianshu.com/p/dd2928490113
1.15java内部类的区别(成员内部类、静态嵌套类、方法内部类、匿名内部类 )。
https://blog.csdn.net/chaseDreamer_/article/details/102859467
j1.16ava线程池参数描述,线程池工作原理,线程池如何调优。
https://blog.csdn.net/qq_30906199/article/details/88554889
1.18主线程到达一个条件,需要多个子线程去执行任务,等子任务都执行完后再往下走,如何编写代码(CountDownLatch)。
1.20写个程序,两个线程交叉打印1到100的数字,需要多种实现方式
2 数据库篇
2.1 查询 第10到20 的数据,分别mysql和oracle 写
mysql:
SELECT * FROM gp_t_project t LIMIT 9,10
注:limit用法
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
//如果只给定一个参数,它表示返回最大的记录行数目:
//查询前十条数据
SELECT * FROM gp_t_project t LIMIT 10
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
//从11 到最后所有数据
SELECT * FROM gp_t_project t LIMIT 10 ,-1
oracle :
需要通过 ROWNUM来实现,先查出rownum 在通过rownum分页
SELECT t.* FROM (SELECT *, ROWNUM rn FROM gp_t_project) t WHERE t.rn >= 10 AND t.rn <= 20
2.2 mysql查询默认不区分大小写
MySql默认查询是不区分大小写的,如果需要区分他,必须在建表的时候,Binary标示敏感的属性.
CREATE TABLE NAME( name VARCHAR(10) BINARY );
在SQL语句中实现 SELECT * FROM TABLE NAME WHERE BINARY name=‘Clip’;
这个可以参考一下连接学习 https://blog.csdn.net/wsgytwsgyt/article/details/80572647
2.3Mysql数据库与Oracle 数据库有什么区别?
应用方面,Mysql 是中小型应用的数据库。一般用于个人和中小型企业。Oracle 属于大型数据库,一般用于具有相当规模的企业应用。
自动增长的数据类型方面: MySQL有自动增长的数据类型。Oracle 没有自动增长的数据类型。需要建立一个自增序列。
group by 用法: Mysql 中group by 在SELECT 语句中可以随意使用,但在ORACLE 中如果查询语句中有组函数,那么其他列必须是组函数处理过的或者是group by子句中的列,否则会报错。
引导方面: MySQL中可以用单引号、双引号包起字符串,Oracle 中只可以用单引号包起字符串
3.算法
3.1 1到100乱序整数中缺少了一个数,怎么快速找出来
思路
方法1: 遍历数组求和 ,用1到100的和减去最后数组算的和
方法2: 先排序 ,再遍历,用arr[i] -i 判断是否不等于1 ,如果不等于1,那么就是那个缺失的