整体准备内容:,希望面试能过!!!!
Java基础核心
1.String a = "123"; String b = "123";String c=new String("123"); a==b的结果是什么? a==c的结果?
答:true,false。a==b指向常量池中的同一个地址。a==c ,由于c是在堆中的对象,而a是常量池中的对象,因此是不同地址。
具体:https://blog.csdn.net/x18094/article/details/113873202
2.==和equals的区别?
答: ==比较的是对象的引用地址,equals比较的是对象内容。
3.||和&&的优先级哪个高?
答:或的优先级高,true || true && false, 先计算或 ,再计算true && false
4.ArrayList和LinkedList底层实现有什么差别?
答: arraylist底层是数组,linkedlist底层是链表。需要保持输入输出顺序时要linkedlist
5.volatile关键字有什么作用?
答: 保证有序性和内存可见性。多线程下需要及时更新值到主存时使用。
6.Java的静态代理和动态代理有什么差别?
答: 静态代理编译前就写好代理类,动态代理则是利用反射在运行时动态生成代理类。
7.String和StringBuffer、StringBuilder有什么区别?
答:String是不可变的,StringBuffer和StringBuilder是可变的。StringBuffer是线程安全的,StringBuilder是不安全的。
8.HashMap的底层结构是什么?
答:数组+链表+红黑树
9.HashMap的Put()方法原理?
答:(1)调用 hash(Key) 方法计算 Key 的 hash 值,再计算得到数组下标。
(2)若key的hash在HashMap中不存在,则插入,若已经存在,发生碰撞。
(3)当发生碰撞时(两个不同的字符串key可能计算出的hash相同)
若key相等,则更新Value。
若key不想等,则加到链表的尾部。
(4)如果放链表时发现当链表长度大于8,且数组长度大于64,把键值对放红黑树(链表转红黑树)。
10.HashMap里的hashcode方法和equal方法什么时候需要重写?
答:对象作为hashmap的key时要重写equals方法,不写equals会不相等。
11.hashmap扩容机制是什么?
答:jdk1.8初始是0,put的时候扩容成16,加载因子默认0.75, 当达到容量的0.75的时候就要扩容,扩容成2倍。
12.hashmap为什么使用红黑树?为什么不直接使用红黑树?
答:数组太长插入慢,链表太长查询慢,二叉树树太高,红黑树通过左旋、右旋变色来平衡二叉树。如果树很短,没必要使用红黑树,因为平衡二叉树也需要消耗,反而更慢。
13.jdk8中对HashMap做了哪些改变?
答:jdk1.8引入了红黑树;hash碰撞时,jdk1.8从链表的尾部插入,而1.7是头插法。
14.ConcurrentHashMap怎么实现线程安全?
答:JDK 1.7 中采用 分段锁的方式;JDK 1.8 中直接采用了CAS(无锁算法)+ synchronized。
class.forName()和classLoader都可用来对类进行加载,它们的区别?
答:Class.forName得到的class是已经初始化完成的
Classloder.loaderClass得到的class是还没有链接的。
class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。"
类实例化执行顺序?
答:父子类静态代码块 static{...}--->main方法----->父子非静态代码块 {...}------>构造函数 ------->一般方法
访问修饰符的作用域?
答:口诀:类包子非,一二三四。 private(1)-default(2)-protected(3)-public(4) ,数字代表几个√
深拷贝和浅拷贝区别?
答:深拷贝会拷贝对象里的引用,比如属性是一个其他对象。浅拷贝不会拷贝属性对象,只是复制了地址。
什么是序列化和反序列化?
答:序列化:对象--》字节;反序列化:字节--》对象
Spring
1.restcontroller 和controller有什么区别?
答:restcontroller=controller+@resposebody
2.controller是单例的吗?
答: 默认是的。scope可设置成多例,作用域:singleton(单例)、prototype(多例)
3.过滤器拦截器有什么区别?
答:过滤器依赖servlet容器,基于函数回调实现,在容器初始化时调用一次,几乎可以过滤所有资源包括静态文件。拦截器基于web框架比如springmvc,基于反射实现运用aop,可以多次调用,但只能拦截controller,无法拦截静态文件。
4.spring bean的生命周期?
答:加载bean定义、bean工厂处理器、实例化、属性赋值、aware接口扩展、beanpost前置处理器、初始化、beanpost后置处理器-bean的使用销毁
5.spring bean的初始化怎么做?
答:1.配置init-method @Bean(init-method="xx") 2.实现InitializingBean方法afterPropertiesSet,3。加@PostConstruct 顺序:postConstruct>afterPropertiesSet>init-method
6.简单说下IOC和AOP?
答:ioc就是权限控制反转,创建对象交给spring容器来做,便于管理。aop就是面向切面编程,它通过动态代理为spring对象增加功能。比如增加日志切面,spirng的事务以及拦截器都是运用了aop。
7.spring的动态代理用哪种实现?
答:spring默认是采用jdk的动态代理,如果想要用cglib可以通过配置文件的方式指定。
8.jdk代理和cglib代理有什么区别?
答:jdk代理利用反射对实现接口的类生成代理,而cglib则利用字节码技术生成一个子类。前者必须是有实现接口才可以,后者则是生成子类,因此目标类不能是final的。
9.spring依赖注入方式有几种,分别是什么?
答:常见的有3种。构造器注入、set方法注入、属性注入(autowire或者resorce)、接口注入(不常用)
10.springmvc流程?
答:面试回答-->(前端控制器(DS)接收请求,然后DS调用处理器映射器HandleMapping,生成处理器对象和拦截器,DS再调用处理器适配器HandleAdapter找到对应的handle,调用handler返回模型视图,DS调用视图解析器解析视图,最后浏览器渲染给用户。)
核心组件:
前端控制器 DispacherServlet
处理器映射器 HandleMapping
处理器适配器 HandleAdapter
Handle
视图解析器 ViewResovle
1.发送请求前端控制器 DispacherServlet
2. DispacherServlet调用处理器映射器HandleMapping,生成处理器对象和拦截器
3.DispatcherServlet 再调用处理器适配器HandleAdapter找到对应的handle
4.调用handle,返回模型视图,前端控制器再调用视图解析器解析视图
5.DispatcherServlet 对视图进行渲染,返回给用户。
11.说说spring mvc用了哪些技术怎么实现的?
答:拦截器 aop技术
12.Spring MVC常用的注解有哪些?
答:@RequestMapping url映射 、@RequestBody 将请求参数转为java对象、@ResponseBody将返回参数转为json格式。
13.springmvc是怎么向前台传递数据的?
答:通过modelMap对象把内容放到里面,前端就可以通过el表达式拿到。
14.springmvc拦截器是怎么写的?
答:实现HandlerInterceptor接口或者继承适配器类
15.WebApplicationContext是什么?
答:继承了ApplicationContext 并增加了一些WEB应用必备的特有功能.
16.springboot/spring常用的注解有哪些?
答:@import @Component @RequestMapping @Pathvariable @Bean @Scope @Configuration @Autowired @RequestBody @ResposeBody
17.怎么保证spring定时任务高可用?两个定时任务同时写表怎么处理的?
答:数据库方面:表主键约束避免重复插入,如果写的频率高,可以用悲观锁的方式,更新的时候加锁for update nowait,数额类更新:如果是累加的,可以写成update a =a+b 的方式,如果本次操作不可抛弃,可以增加重试功能。如果写的频率不高,可以用乐观锁,增加版本号字段来控制,写的时候带上版本号去更新。
18.说说springboot自动配置原理?
答:面试回答-->(springboot注解会引入后缀是xxImportSelector类,里面有selectImorts方法,它会寻找META-INF/spring.factories配置文件,找到里面的自动配置类,根据自动配置类进行装配。)
详细:
@SpringBootApplication里有@EnableAutoConfiguration ,@EnableAutoConfiguration里再@Import({EnableAutoConfigurationImportSelector.class})
他的父类AutoConfigurationImportSelector里面的selectImports方法会去寻找META-INF/spring.factories配置文件,配置文件里配置的EnableAutoConfiguration的自动配置类(比如springboot-autoconfigure META-INF/spring.factories 自动配置类)
根据自动配置类进行装配
19.Spring cloud知道多少?
答:五大组件eureka、zuul、Hystrix、ribbon、springcloud config,以及服务调用feign
20.@Autowired/@Resource的区别?
答:@Autowired是Spring的注解,Autowired默认先按byType,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常。@Resource是jdk的注解,默认按名称装配,如果装配失败,按类型。
21.BeanFactory 和ApplicationContext的区别?
答:BeanFactory提供基本功能(实例化对象和获取对象),ApplicationContext提供更多的功能包括aop。装载bean方面,BeanFactory在拿bean的时候才实例化,ApplicationContext在启动的时候全部实例化。
22.Spring 定时任务执行原理是什么?
答:Spring 将会优先查找 TaskScheduler/ScheduledExecutorService的实例,若存在将会使用。如果不存在则使用的是 JDK 自带的 ScheduledExecutorService的默认配置。
23.spring执行多个定时任务怎么做?
答:配置一个TaskScheduler,设置好线程池大小,增加到spring容器中。如果不配置,则多个任务可能会互相影响(等待)。
24.spring是如何解决循环依赖的?
答:面试回答--》简单来说,主要是有三级缓存,在里面有发现循环依赖,就会临时放到二级缓存(表示有循环依赖的),最后都放到一级缓存里面去。
1.对象A一开始会放入三级缓存( singletonFactories),发现依赖B,也放入三级缓存;2.开始注入B中的依赖A时,把A从三级移到二级(删除三级中A);3.把B放进一级缓存,删除三级,完成B的注入;4.把A也放入一级缓存,删除二级缓存,完成A的注入。至此A,B注入完成。
详细:
假设对象A中有属性是对象B,对象B中也有属性是对象A,即A和B循环依赖。
1.创建对象A,调用A的构造,并把A保存下来。
2.然后准备注入对象A中的依赖,发现对象A依赖对象B,那么开始创建对象B。
3.调用B的构造,并把B保存下来。
4.然后准备注入B的构造,发现B依赖对象A,对象A之前已经创建了,直接获取A并把A注入B(注意此时的对象A还没有完全注入成功,对象A中的对象B还没有注入),于是B创建成功。
5.把创建成功的B注入A,于是A也创建成功了。
于是循环依赖就被解决了。
singletonObjects:单例对象的cache,一级缓存
earlySingletonObjects :二级缓存,提前暴光的单例对象的Cache 。【用于检测循环引用,与singletonFactories互斥】
singletonFactories : 单例对象工厂的cache ,三级缓存
步骤 | 操作 | 三层列表中的内容 |
---|---|---|
1 | 开始初始化对象A | singletonFactories: earlySingletonObjects: singletonObjects: |
2 | 调用A的构造,把A放入singletonFactories | singletonFactories:A earlySingletonObjects: singletonObjects: |
3 | 开始注入A的依赖,发现A依赖对象B | singletonFactories:A earlySingletonObjects: singletonObjects: |
4 | 开始初始化对象B | singletonFactories:A,B earlySingletonObjects: singletonObjects: |
5 | 调用B的构造,把B放入singletonFactories | singletonFactories:A,B earlySingletonObjects: singletonObjects: |
6 | 开始注入B的依赖,发现B依赖对象A | singletonFactories:A,B earlySingletonObjects: singletonObjects: |
7 | 开始初始化对象A,发现A在singletonFactories里有,则直接获取A, 把A放入earlySingletonObjects,把A从singletonFactories删除 |
singletonFactories:B earlySingletonObjects:A singletonObjects: |
8 | 对象B的依赖注入完成 | singletonFactories:B earlySingletonObjects:A singletonObjects: |
9 | 对象B创建完成,把B放入singletonObjects, 把B从earlySingletonObjects和singletonFactories中删除 |
singletonFactories: earlySingletonObjects:A singletonObjects:B |
10 | 对象B注入给A,继续注入A的其他依赖,直到A注入完成 | singletonFactories: earlySingletonObjects:A singletonObjects:B |
11 | 对象A创建完成,把A放入singletonObjects, 把A从earlySingletonObjects和singletonFactories中删除 |
singletonFactories: earlySingletonObjects: singletonObjects:A,B |
12 | 循环依赖处理结束,A和B都初始化和注入完成 | singletonFactories: earlySingletonObjects: singletonObjects:A,B |
其实最关键的是,为什么会出现循环依赖?
假如说只有一级缓存singletonObjects,A对象创建后放进来,再注入B,B对象创建后也放进singletonObjects。。。。B中也有依赖A,又会创建A对象。。。。所以问题的关键是:怎么取已经创建的对象,而三级缓存的作用就是为了:可以发现是否已经有对象的实例创建好了。
@Transitional失效的情况?
答:springmvc下controller上的@Transactional不生效;检查型异常不回滚,如FileNotFoundException;只作用在public修饰符上
Springmvc 中 DispatcherServlet 初始化过程
答:入口是web.xml中配置的ds,ds继承了HttpServletBean,FrameworkServlet,通过其中的init方法进行初始化装载bean和实例,initServletBean是实际完成上下文工作和bean初始化的方法。
JVM
1.JVM里,new出来的对象是在哪个区?
答:new出来的对象放在堆里,对象的引用放在栈里。
2.说说类加载有哪些步骤?
答:类加载分三步:加载、连接(验证、准备和解析)和初始化。
加载:class文件加载到JVM内存(静态变量、常量放到方法区),产生Class对象。
验证:验证class文件是否格式正确。
准备:为静态变量分配内存并设置默认的初始值
解析:将符号引用替换为直接引用 (栈帧里的动态链接也有一步符号引用转变为直接引用)
初始化:为类的静态变量赋予正确的初始值
3.说说JVM内存模型?
答:是一种规范,与线程共享有关,堆和方法区所有线程共享,需要对其制定规则规范。主内存:java所有变量都存储在主内存中。工作内存/线程本地内存:本线程用到的变量为主存中的副本拷贝。
4.说说JVM内存结构分别放什么?
答:堆:对象和数组、字符串常量池。方法区:常量、静态变量,运行时常量池(字面量和符号引用)。虚拟机栈:局部变量、对象引用。程序计数器:记录线程执行位置,以便下一次继续执行。
本地方法栈:是一些native方法(c++实现)
5.说说常用的JVM参数?
答:-Xms128m -Xmx128m Xmn1g -XX:SurvivorRatio=4 -XX:+UseG1GC
6.说说常用的JVM调优命令?
答:jps jstack jinfo jmap jstat
7.你知道反汇编吗?
答:知道。会使用javap反汇编解读i++操作原理 ,反汇编后得到JVM指令,可以通过官方文档查看JVM指令集的解释。
javap -c xx.class
8.说说高cpu的排查过程?
答:top命令找到进程号,用ps命令找到线程号,然后转为16进制,最后使用jstack命令找到该线程号堆栈位置。
9.堆栈溢出如何跟踪?
答:事先启动增加堆溢出跟踪日志参数-XX:+HeapDumpOnOutOfMemoryError ,用mat工具查看。
10.说说一次GC流程是怎么样的?
答:普通对象进入年轻代eden区,大对象直接进入老年代。
年轻代回收机制:
1.对象进入伊甸区,填满后触发一次minor gc,还存活的对象会复制到其中一个存活区s0并清空伊甸区。
2.当伊甸区再一次填满后,再次触发minor gc,jvm会把伊甸区和s0还存活的对象复制到另一个存活区s1,同时清空伊甸区和s0区。
3.如果复制的过程发现空间不够,就会搬到老年代。
4.如果minorgc达到15次就会搬到老年代。
11.什么是stop the world(STW)?
答:GC前会执行STW操作。线程进入JVM设置的“安全点”,暂停所有运行中的线程,stop the world,然后开始GC。
什么情况下会发生栈内存溢出?
答:递归。
什么情况下发生堆溢出?
答:对象一直增大,不释放。 比如循环里一直list.add
g1 和 cms 区别?
答:Cms是以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。比较占用cpu资源,切易造成碎片。 G1是面向服务端的垃圾收集器,是jdk9默认的收集器,基于标记-整理算法实现。可利用多核、多cpu,保留分代,实现可预测停顿,可控。
SQL
1.什么是三范式和反三范式?(表设计)
答:1NF:每列属性唯一;2NF主键唯一;3NF属性不能与其他表属性产生冗余。反三范式:避免过多的关联查询,可以降低范式标准,适当冗余。
2.SQL优化常见的方式?
答:避免全表扫描、合理使用索引、避免返回大量数据给客户端、避免使用游标、避免频繁创建删除临时表。
3.oracle解析器解析顺序?
答:从右到左的顺序处理FROM子句中的表名,记录数少的表写在右边作为基础表。WHERE 解析自下而上,过滤大数据量的条件放后面。
4.ORACLE分页怎么做?
答:用rownum select xx from (select xx, rownum r from test1) tt where tt.r < 100;
5.行列转换怎么做?
答:1.decode函数或者case when;2.通过map_agg函数把两个列的多行的值,映射为map;3.通过UNION语句
6.oracle怎么查树?
答:用start with conect by 。 具体:start with pid=0 connect by (prior id)=pid
7.索引查询快的原因,索引使用什么排序?
答:索引就是以空间换时间,以特定的数据结构重新存储数据,减少查询次数。mysql就是用b+树
linux
1.说说你常用的命令?
答:ps 、grep、find 、more 、less、 top、du、df、touch、chmod
2.怎么查找文件中的字符串?
答:如果只要找到字符串的那一行,用grep字符 文件名的方式,如果要找到字符串并且要能看到上下文,就用less,用斜杠加字符串查找,用n/N往上下查找。
less -mN a.txt 查看文件,/wzx 查找字符串,n继续往下找,N网上找。g跳到第一行,G跳到最后一行,q 退出
grep wzx a.txt 查找文件内容包含字符串
3.怎么查看java进程?
答:可以用jps,也可以用ps -ef|grep
ps -ef |grep xxx 查看进程
4.怎么查看cpu占用情况?
答:top 查看cpu占用情况
5.怎么查看磁盘占用情况?
答:df 查看磁盘占用情况
du * -sh 查看当前文件夹下空间占用(包含文件夹统计) ll -h 也可以查看文件占用
6.怎么更改环境变量?
vi /etc/profile 所有用户 。 立即生效:source /etc/profile
vi ~/.bash_profile 更改当前用户环境变量。立即生效: source ~/.bash_profile
7.你知道怎么自定义一个自己的命令吗?
答:写好命令脚本,然后再环境变量增加自定义命令文件扫描路径,并且立即生效。
多线程
1.说说常用的线程池有哪些?
答:定长线程池(FixedThreadPool)、缓存线程池(CachedThreadPool)、单线程线程池(SingleThreadExecutor)、周期线程池
2.那你知道多线程JDK8有什么新特性?
答:增加异步编程CompletableFuture。可以对返回结果进行集中处理。
3.说说ThreadPoolExecutor有几个参数,分别是什么意思?
答:7个参数。核心线程大小、最大线程数、非核心线程超时时间、单位、阻塞队列、线程工厂、拒绝策略handle
4.线程有几种拒绝策略,分别是什么?实际应该怎么使用?
答:我知道有4种。单词记不住,面试回答--》一种是直接抛异常,一直是直接丢弃任务,还有一种是抛弃等待最久的任务,另外一种我忘了。
具体:
AbortPolicy 直接抛异常,程序中断。;CallerRunsPolicy 回退调用者
DiscardOldestPolicy 抛弃队列种等待最久的任务,尝试提交 DiscardPolicy 直接丢弃任务
使用:
具体使用要根据业务来,如果业务可以支持抛异常就用抛异常,如果任务可以丢弃就用丢弃策略,没有特定的方式。我看过一个框架重写的拒绝策略是什么都不处理,具体是哪个我忘了好像是apache。
5.说说线程池工作的过程?
答:面试回答--》1.线程池添加任务,小于核心线程数,就创建执行;2.如果大于核心数,就进入阻塞队列;3.如果阻塞队列满了,就创建非核心线程执行新添加的任务;4.如果全满了,就根据拒绝策略处理。
详细:
1.线程池创建
2.执行execute()添加任务时:
执行execute()添加任务时:
当前线程数小于核心线程数,立即创建线程并运行。
否则,进入阻塞队列等待。
如果队列满了,就会创建非核心线程并立即执行。(注意,此时阻塞队列里的任务仍然在等待)。
如果还有任务进来,并且此时运行线程大于等于最大线程数,则启动饱和拒绝策略。
3.当线程中任务执行完成时,从队列取任务。
4.如果一个线程空闲,会根据空闲时间,判断是否大于核心线程数,如果大于就销毁线程,释放内存。
用过哪些原子类,他们的原理是什么?
答:AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基于CAS原语实现 ,比较并交换、加载链接/条件存储,最坏的情况下是旋转锁
创建多少线程数合适?
答:CPU 密集型(例如:1-1000 万累加计算)则是 CUP核心数+1,如果是IO 密集型(数据库访问,远程调用)则是:最佳线程数 = (1/CPU利用率) = 1 + (I/O耗时/CPU耗时)
Threadlocal原理和作用?
答:作用:每个线程提供变量副本,起到线程隔离的作用。原理:每个ThreadLocal类创建一个Map,然后用线程的ID作为Map的key,实例对象作为Map的value,这样就能达到各个线程的值隔离的效果。
countdowlatch 和 cyclicbarrier 的作用?
答:CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它运行一个或者多个线程一直处于等待状态。 CyclicBarrier要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
使用 synchronized 修饰静态方法和非静态方法有什么区别?
答:对象锁和类锁
死锁产生的原因?
答:两个以上线程,争抢对方手中的资源,而自身又不释放。
Redis
这边看你写了解一点redis,能说说你是怎么用的吗?
答:redis就是说,读的次数远大于写的次数,这个使用可以用redis作为缓存,提高读的效率。
缓存击穿、缓存穿透、缓存雪崩是什么?怎么解决?
答:缓存击穿:缓存没数据,数据库有数据,一般发生在过期的时候,给数据库压力。解决:热点数据永不过期,或者解锁,第一个进来锁上,第二个线程进来等待100ms再重新获取。
缓存穿透:缓存和数据库都找不到,用户一直去访问,造成数据库压力。解决:可以给KEY设置一个null值,然后设置一个很短的时间比如5分钟过期时间或者接口层增加id递减判断,如果小于0就拦截,或者用布隆过滤器。
缓存雪崩:就是同一时间大批量的KEY都过期了。可以分散它的过期时间来解决。
布隆过滤器的原理是什么?
答:就是把可能存在的哈希数据放到一个大的bitmap中,然后一个一定不存在的数据进来,就会被过滤掉。
友情链接:
程序员搞什么副业好?https://blog.csdn.net/x18094/article/details/113782544