一、自我介绍、本身作的项目和技术领域java
开放题web
二、项目中的监控:那个监控指标常见的有哪些?算法
答:CPU、内存、IO 等等。建议下载个nmon工具,里面有各个指标。spring
数据库:Mysql(缓存命中、索引、单条SQL性能、数据库线程数、数据池链接数)sql
中间件:1.消息二、负载均衡三、缓存(包括线程数、链接数、日志)。数据库
网络: 吞吐量、吞吐率编程
应用: jvm内存、日志、Full GC频率json
三、微服务涉及到的技术以及须要注意的问题有哪些?api
四、注册中心你了解了哪些?数组
答:Consul 、Eureka、ZooKeeper
五、consul 的可靠性你了解吗?
六、consul 的机制你有没有具体深刻过?有没有和其余的注册中心对比过?
七、项目用 Spring 比较多,有没有了解 Spring 的原理?AOP 和 IOC 的原理
答:(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。
(2). 在Spring的工做方式中,全部的类都会在spring容器中登记,告诉spring这是个什么东西,你须要什么东西,而后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其余须要你的东西。全部的类的建立、销毁都由 spring来控制,也就是说控制对象生存周期的再也不是引用它的对象,而是spring。对于某个具体的对象而言,之前是它控制其余对象,如今是全部对象都被spring控制,因此这叫控制反转。
(3). 在系统运行中,动态的向某个对象提供它所须要的其余对象。
(4). 依赖注入的思想是经过反射机制实现的,在实例化一个类时,它经过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。 总而言之,在传统的对象建立方式中,一般由调用者来建立被调用者的实例,而在Spring中建立被调用者的工做由Spring来完成,而后注入调用者,即所谓的依赖注入or控制反转。 注入方式有两种:依赖注入和设置注入; IoC的优势:下降了组件之间的耦合,下降了业务对象之间替换的复杂性,使之可以灵活的管理对象。
AOP(Aspect Oriented Programming)
(1). AOP面向方面编程基于IoC,是对OOP的有益补充;
(2). AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的 逻辑或责任封装起来,好比日志记录,便于减小系统的重复代码,下降模块间的耦合度,并有利于将来的可操做性和可维护性。
(3). AOP表明的是一个横向的关 系,将“对象”比做一个空心的圆柱体,其中封装的是对象的属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,选择性的提供业务逻辑。而 剖开的切面,也就是所谓的“方面”了。而后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。
(4). 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法建立“方面”,从而使得编译器能够在编译期间织入有关“方面”的代码。
(5). Spring实现AOP:JDK动态代理和CGLIB代理 JDK动态代理:其代理对象必须是某个接口的实现,它是经过在运行期间建立一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHandler和Proxy。 CGLIB代理:实现原理相似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操做字节码实现的,性能比JDK强;须要引入包asm.jar和cglib.jar。 使用AspectJ注入式切面和@AspectJ注解驱的切面实际上底层也是经过动态代理实现的。
(6). AOP使用场景:
Authentication 权限检查
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 延迟加载
Debugging 调试
logging, tracing, profiling and monitoring 日志记录,跟踪,优化,校准
Performance optimization 性能优化,效率检查
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务管理
另外Filter的实现和struts2的拦截器的实现都是AOP思想的体现。
八、Spring Boot除了自动配置,相比传统的 Spring 有什么其余的区别?
为Spring 生态系统的开发提供一种更简洁的方式,提供了不少非功能性特性,例如:嵌入式 Server,Security,统计,健康检查,外部配置等等,主要体如今如下几点:
1.Spring Boot能够创建独立的Spring应用程序;
2.内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说能够直接跑起来,用不着再作部署工做了;
3.无需再像Spring那样搞一堆繁琐的xml文件的配置;
4.能够自动配置Spring。SpringBoot将原有的XML配置改成Java配置,将bean注入改成使用注解注入的方式(@Autowire),并将多个xml、properties配置浓缩在一个appliaction.yml配置文件中。
5.提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
6.整合经常使用依赖(开发库,例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM能够简化Maven的配置。当咱们引入核心依赖时,SpringBoot会自引入其余依赖。
九、Spring Cloud 有了解多少?
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,均可以用Spring Boot的开发风格作到一键启动和部署。Spring Cloud并无重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,经过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
十、Spring Bean 的生命周期
一个Bean从建立到销毁,若是是用BeanFactory来生成,管理Bean的话
Spring上下文中的Bean也相似,以下
一、实例化一个Bean--也就是咱们常说的new;
二、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
三、若是这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
四、若是这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(能够用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就能够);
五、若是这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(一样这个方式也能够实现步骤4的内容,但比4更好,由于ApplicationContext是BeanFactory的子接口,有更多的实现方法);
六、若是这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean内容的更改,而且因为这个是在Bean初始化结束时调用那个的方法,也能够被应用于内存或缓存技术;
七、若是Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
八、若是这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工做完成之后就能够应用这个Bean了,那这个Bean是一个Singleton的,因此通常状况下咱们调用同一个id的Bean会是在内容地址相同的实例,固然在Spring配置文件中也能够配置非Singleton,这里咱们不作赘述。
九、当Bean再也不须要时,会通过清理阶段,若是Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
十、最后,若是这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
另外咱们这里描述的是应用Spring上下文Bean的生命周期,若是应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了
十一、HashMap 和 hashTable 区别?
区别:Hashtable是线程安全的,效率比较低
Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的注释中有说明
Hashtable默认的初始大小为11,以后每次扩充,容量变为原来的2n+1。
HashMap默认的初始化大小为16。以后每次扩充,容量变为原来的2倍
Hashtable在计算元素的位置时须要进行一次除法运算,而除法运算是比较耗时的
HashMap为了提升计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不须要作除法,只须要作位运算。位运算比除法的效率要高不少。
HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口
十二、Object 的 hashcode 方法重写了,equals 方法要不要改?
不须要,Ojbect类中有两个方法equals、hashCode,这两个方法都是用来比较两个对象是否相等的,若是两个对象相等(equal),那么必须拥有相同 的哈希码(hash code)
即便两个对象有相同的哈希值(hash code),他们不必定相等
重写equals()方法就必须重写hashCode(),但重写hashcode方法不必定要重写equals方法
1三、Hashmap 线程不安全的出现场景
用ConcurrentHashMap 线程安全
多线程处理时hashmap线程不安全
首先hashmap里这个size没有用volatile关键字修饰,表明这不是一个内存可见的变量,线程操做数据的时候通常是从主存拷贝一个变量副本进行操做,操做完成事后在把size的值写回到主存size的
线程不安全问题应该属于并发问题之一的,属于相对高级的问题了。这个时候的问题已经不只仅局限于代码层面了,不少时候须要结合JVM一块儿分析了
1四、线上服务 CPU 很高该怎么作?有哪些措施能够找到问题
定位出现问题的堆栈信息排查具体问题
一、top命令:Linux命令。能够查看实时的CPU使用状况。也能够查看最近一段时间的CPU使用状况。
二、ps命令: Linux命令。强大的进程状态监控命令。能够查看进程以及进程中线程的当前CPU使用状况。属于当前状态的采样数据。
三、jstack: Java提供的命令。能够查看某个进程的当前线程栈运行状况。根据这个命令的输出能够定位某个进程的全部线程的当前运行状态、运行代码,以及是否死锁等等。
四、pstack:Linux命令。能够查看某个进程的当前线程栈运行状况
1五、JDK 中有哪几个线程池?顺带把线程池讲了个遍
JUC提供了调度器对象Executors来建立线程池,可建立的线程池有四种
一、newFixedThreadPool建立一个指定工做线程数量的线程池。每当提交一个任务就建立一个工做线程,若是工做线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
二、newCachedThreadPool建立一个可缓存的线程池。这种类型的线程池特色是:
1).工做线程的建立数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
2).若是长时间没有往线程池中提交任务,即若是工做线程空闲了指定的时间(默认为1分钟),则该工做线程将自动终止。终止后,若是你又提交了新的任务,则线程池从新建立一个工做线程。
三、newSingleThreadExecutor建立一个单线程化的Executor,即只建立惟一的工做者线程来执行任务,若是这个线程异常结束,会有另外一个取代它,保证顺序执行(我以为这点是它的特点)。单工做线程最大的特色是可保证顺序地执行各个任务,而且在任意给定的时间不会有多个线程是活动的 。
四、newScheduleThreadPool建立一个定长的线程池,并且支持定时的以及周期性的任务执行,相似于Timer。(这种线程池原理暂还没彻底了解透彻)
1五、SQL 优化的常见方法有哪些
查询条件减小使用函数,避免全表扫描
减小没必要要的表链接
有些数据操做的业务逻辑能够放到应用层进行实现
可使用with as
尽可能避免使用游标,由于游标的效率较差
不要把SQL语句写得太复杂
不能循环执行查询
用 exists 代替 in
表关联关系不要太纠结
查询多用索引列取查,用charindex或者like[0-9]来代替%%
inner关联的表能够先查出来,再去关联leftjoin的表
能够进行表关联数据拆分,即先查出核心数据,再经过核心数据查其余数据,这样会快得多
参考SQL执行顺序进行优化
表关联时取别名,也能提升效率
使用视图,给视图创建索引进行优化
使用数据仓库的形式,创建单独的表存储数据,根据时间戳按期更新数据。将多表关联的数据集中抽取存入一张表中,查询时单表查询,提升了查询效率
对查询进行优化,应尽可能避免全表扫描,首先应考虑在 where 及 order by 涉及的列上创建索引
应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
能够在num上设置默认值0,确保表中num列没有null值,而后这样查询:
select id from t where num=0
16.应尽可能避免在 where 子句中使用!=或<>操做符,不然将引擎放弃使用索引而进行全表扫描
1七、SQL 索引的顺序,字段的顺序
1八、查看 SQL 是否是使用了索引?(有什么工具)
在select语句前加上EXPLAIN便可
1九、TCP 和 UDP 的区别?TCP 数据传输过程当中怎么作到可靠的?
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种
1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
(2)并为每一个已发送的数据包启动一个超时定时器;
(3)如在定时器超时以前收到了对方发来的应答信息(多是对本包的应答,也能够是对本包后续包的应答),则释放该数据包占用的缓冲区;
(4)不然,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后,先进行CRC校验,若是正确则把数据交给上层协议,而后给发送方发送一个累计应答包,代表该数据已收到,若是接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
20、说下你知道的排序算法吧
常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等
2一、查找一个数组的中位数?
经过二分查找法来找中位数
基本思想是:假设ar1[i]是合并后的中位数,那么ar1[i]大于ar1[]中前i-1个数,且大于ar2[]中前j=n-i-1个数。经过ar1[i]和ar2[j]、ar2[j+1]两个数的比较,在ar1[i]的左边或者ar1[i]右边继续进行二分查找。对于两个数组 ar1[] 和ar2[], 先在 ar1[] 中作二分查找。若是在ar1[]中没找到中位数, 继续在ar2[]中查找。
算法流程:
1) 获得数组ar1[]最中间的数,假设下标为i.
2) 计算对应在数组ar2[]的下标j,j = n-i-1
3) 若是 ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1],那么 ar1[i] 和 ar2[j] 就是两个中间元素,返回ar2[j] 和 ar1[i] 的平均值
4) 若是 ar1[i] 大于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的左部分作二分查找(i.e., arr[left ... i-1])
5) 若是 ar1[i] 小于 ar2[j] 和 ar2[j+1] 那么在ar1[i]的右部分作二分查找(i.e., arr[i+1....right])
6) 若是到达数组ar1[]的边界(left or right),则在数组ar2[]中作二分查找
时间复杂度:O(logn)。
欢迎工做一到五年的Java工程师朋友们加入Java高级架构:867581223
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)
合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!