记一次面试
记第一次面试 菜鸡如我,简单总结一下
-
MySQL怎样结果去重?
关键字 distinct
SELECT DISTINCT columnname FROM tablename
-
字符串的操作?(切割字符串)
substring()方法
substring(int start)//从start开始截取字符串 String substring(int start,int end)//从start开始,到end结束截取字符串。包括start,不包括end
-
接口和抽象类的区别
-
接口
接口使用interface修饰;
接口不能实例化;
类可以实现多个接口;接口的字段默认都是 static 和 final 的
①java8之前,接口中的方法都是抽象方法,省略了public abstract。②java8之后;接口中可以定义静态方法,静态方法必须有方法体,普通方法没有方法体,需要被实现;
-
抽象类
抽象类使用abstract修饰;
抽象类不能被实例化;
抽象类只能单继承;
抽象类中可以包含抽象方法和非抽象方法,非抽象方法需要有方法体;
如果一个类继承了抽象类,①如果实现了所有的抽象方法,子类可以不是抽象类;②如果没有实现所有的抽象方法,子类仍然是抽象类。
抽象类和接口都可以作为声明使用,都不能被实例化。
-
-
HashMap的实现原理?(没理解问的啥)
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的组成?
java1.8之前是数组+链表 1.8之后数组+链表+红黑树
HashMap 基于 Hash 算法实现的
-
当我们往HashMap中put元素时,利用key的HashCode重新hash,计算出当前对象的元素在数组中的下标
-
存储时,如果出现hash值相同的key,此时有两种情况。
(1)如果key相同,则覆盖原始值;
(2)如果key不同(出现冲突),则将当前的key-value放入链表中
-
获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
HashMap解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
扩容
当HashMap中的其中一个链表的对象个数如果达到了8个,此时如果数组长度没有达到64,那么HashMap会先扩容解决,如果已经达到了64,那么这个链表会变成红黑树,节点类型由Node变成TreeNode类型。当然,如果映射关系被移除后,下次执行resize方法时判断树的节点个数低于6,也会再把树转换为链表。
-
-
SpringBoot的启动注解?
@SpringBootApplication
-
自动注解的实现原理?(没听清)
@SpringBootApplication这个注解其实是一个复合注解,主要由以下几个重要部分组成:
(1)@SpringBootConfiguration:这个注解的底层是一个@Configuration注解,意思被@Configuration注解修饰的类是一个IOC容器,支持JavaConfig的方式来进行配置;
(2)@ComponentScan:这个就是扫描注解的意思,默认扫描当前类所在的包及其子包下包含的注解,将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中;
(3)@EnableAutoConfiguration:这个注解表明启动自动装配,里面包含两个比较重要的注解@AutoConfigurationPackage和@Import。
总结:
SpringBoot启动的时候通过@EnableAutoConfiguration注解找到META-INF/spring.factories文件中的所有自动配置类,并对其加载,这些自动配置类都是以AutoConfiguration结尾来命名的。它实际上就是一个JavaConfig形式的IOC容器配置类,通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如server.port。
*Properties类的含义:封装配置文件的相关属性。
*AutoConfiguration类的含义:自动配置类,添加到IOC容器中。 -
SpringCloud的组件有哪些?(两次)
(1)服务的注册与发现:Eureka,Nacos,Zookeeper
(2)负载均衡:Ribbon
(3)声明式的 Web 服务客户端,服务调用:Feign、OpenFeign
(4)断路器:Hystrix(熔断器)
(5)网关:Zuul,gateway
-
Eureka的自我保护机制(和心跳机制弄混了)
为了防止EurekaClient可以正常运行,但是 与 EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除,这是就会产生自我保护机制,在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当网络故障恢复后,该EurekaServer节点会自动的退出自我保护机制
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存,当故障恢复时,自动退出自动保护机制。
-
Eureka的心跳机制
在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)
-
Eureka(Ribbon)和Nginx的区别?
Nginx 是客户端所有请求统一交给 nginx,由 nginx 进行实现负载均衡请求转发,属于服务器端负载均衡。它是一种集中式的负载均衡器。即请求由 nginx 服务器端进行转发。
Ribbon 是从 eureka 注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮询负载均衡策略。即在客户端实现负载均衡。
区别:
1)Nginx 适合于服务器端实现负载均衡 比如 Tomcat
2)Ribbon 适合与在微服务中 RPC 远程调用实现本地服务负载均衡,比如 Dubbo、SpringCloud 中都是采用本地负载均衡。
-
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。
-
线程安全的集合有哪些?
Vector:比ArrayList多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率是优先考虑的。
Stack:堆栈类,先进后出。
HashTable:比HashMap多了个线程安全。效率低ConcurrentHashMap:避免了对全局加锁改成了局部加锁操作,
Enumeration:枚举,相当于迭代器。
-
HashTable为什么是线程安全的?
HashTable
使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。
ConcurrentHashMap 和 HashTable 的区别主要体现在实现线程安全的方式上不同。
-
底层数据结构: JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。HashTable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
-
实现线程安全的方式(重要): ① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。(默认分配16个Segment,比Hashtable效率提高16倍。) 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。
-
。。。(结束了,凉了)
上一篇: JS二叉树的简单实现方法示例
下一篇: 百度运维开发面试