java基础
ArrayList 和 linkedList 区别及底层代码及时间复杂度
List常用的ArrayList和LinkedList使用场景?
ArrayList底层使用的是数组,LinkedList使用的是链表。
数组查询具有所有查询特定元素比较快,而插入和删除和修改比较慢(数组在内存中是一块连续的内存,如果插入或删除是需要移动内存)。
链表不要求内存是连续的,在当前元素中存放一个或上一个元素的地址。查询时需要从头部开始,一个一个的找,所以查询效率低。插入时不需要移动内存,只需改变引用指向即可,所以插入或者删除的效率高。
结论:ArrayList使用在查询比较多,但是插入和删除比较少的情况,而LinkedList使用在查询比较少而插入和删除比较多的情况。
HsahMap 源码解读,底层结构及扩容规则
HashMap在底层数据结构上采用了数组+链表+红黑树,通过散列映射来存储键值对数据因为在查询上使用散列码(通过键生成一个数字作为数组下标,这个数字就是hash code)所以在查询上的访问速度比较快,HashMap最多允许一对键值对的Key为Null,允许多对键值对的value为Null。它是非线程安全的。在排序上面是无序的。
如果存在Hash碰撞就会以链表的形式保存,把当前传进来的参数生成一个新的节点保存在链表的尾部(JDK1.7保存在首部)。而如果链表的长度大于8那么就会以红黑树的形式进行保存。
扩容机制核心方法Node<K,V>[] resize():
HashMap扩容可以分为三种情况:
第一种:使用默认构造方法初始化HashMap。从前文可以知道HashMap在一开始初始化的时候会返回一个空的table,并且thershold为0。因此第一次扩容的容量为默认值DEFAULT_INITIAL_CAPACITY也就是16。同时threshold = DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR = 12。
第二种:指定初始容量的构造方法初始化HashMap。那么从下面源码可以看到初始容量会等于threshold,接着threshold = 当前的容量(threshold) * DEFAULT_LOAD_FACTOR。
第三种:HashMap不是第一次扩容。如果HashMap已经扩容过的话,那么每次table的容量以及threshold量为原有的两倍。
这边也可以引申到一个问题就是HashMap是先插入数据再进行扩容的,但是如果是刚刚初始化容器的时候是先扩容再插入数据。
参考链接:
CurrentMap 为何效率高切是线程安全的 怎么找到16分区并对指定分区加锁
主要是实现分段锁,源码里面有public boolean containsValue(Object value)这个方法主要是给所有segment加锁。
参考链接:
为什么使用占位符
增加SQL代码可读性、占位符可以预先编译,提高执行效率、防止SQL注入、用占位符的目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少。
java 1.5 1.6 1.7 1.8 的区别及特性及项目中的使用
java1.5新特性:自动装箱和拆箱功能、可变参数、for-each,增强for循环、枚举、静态导入、泛型、线程并发库、注解。
java1.6新特性:在awt中新增Desktop类与SystemTray类、使用JAXB2来实现对象与XML之间的映射、理解StAx、使用Compiler API实现动态编译、轻量级Http Server API、插入式注解处理API、用Console开发控制台程序、对脚本语言的支持 如:ruby,groovy,javascript、Common Annotations。
java1.7新特性:二进制面值、数字变量对下划线的支持、switch支持部分基本数据类型(primitive data types)与枚举类型,如:byte、short、int、long、char;不支持boolean、float、double,增加对String的支持、try - with - resource 自动资源管理、捕获多种异常并用改进后的类型检查来重新抛出异常、创建泛型时类型推断。
java1.8新特性:Lambdas表达式与Functional接口、接口的默认与静态方法、方法引用、重复注解、更好的类型推测机制、扩展注解的支持。
日志需要注意什么
Log上下文(在Log中必须尽量带入上下文的信息,对比以下两个Log信息,后者比前者更有作用)、Error或者Warn级别中碰到Exception的情况尽量log完整的异常信息、对与不是特别重要的异常,不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次。
有意义的日志:通常情况下在程序日志里记录一些比较有意义的状态数据:程序启动,退出的时间点;程序运行消耗时间;耗时程序的执行进度;重要变量的状态变化。除此之外,在公共的日志里规避打印程序的调试或者提示信息。
参考链接:
你常用的流,在工作中如何使用的
字节流,因为图像、音频、文件、读取都是字节流啊,工作中使用主要看场景了。
javaNIO 与netty NIO
多线程安全问题,线程池使用,不用锁如何实现线程安全,怎样合理使用线程池,你在项目组如何使用的
Java通过Executors提供了四种线程池,分别为:
1.newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2.newFixedThreadPool创建一个定长线程池,可控制线程池最大并发数,超出的线程会在队列中等待。
3.newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行。
借助CAS(AtomicReference)实现单例模式
public class Singleton {
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();
private Singleton() {}
public static Singleton getInstance() {
for (;;) {
Singleton singleton = INSTANCE.get();
if (null != singleton) {
return singleton;
}
singleton = new Singleton();
if (INSTANCE.compareAndSet(null, singleton)) {
return singleton;
}
}
}
}
用CAS的好处在于不需要使用传统的锁机制来保证线程安全,CAS是一种基于忙等待的算法,依赖底层硬件的实现,相对于锁它没有线程切换和阻塞的额外消耗,可以支持较大的并行度。CAS的一个重要缺点在于如果忙等待一直执行不成功(一直在死循环中),会对CPU造成较大的执行开销。
jvm 内存模型,jvm调优
tomcat调优
gc 原理
数据库
怎样防止sql注入
1、(简单又有效的方法)PreparedStatement使用占位符。
2、使用正则表达式过滤传入的参数。
3、字符串过滤。
分库分表分区及如何查询
参考链接:
索引数据结构及索引原理
单列,多列索引等优化
表关联,子查询需要注意的问题
sql慢查询分析
参考链接:
慢查询定位。
数据库事务及隔离级别及常见问题及解决方案
参考链接:
数据库的悲观锁和乐观锁
参考链接:
redis
常见数据类型
字符串string。
列表list。
散列hash。
集合set。
有序集合sorted set。
应用常见
缓存:把经常需要查询的、很少修改的数据,放到读速度很快的空间(内存),以便下次访问减少时间,减轻压力,减少访问时间。
计数器:Redis中的计数器是原子性的内存操作。可以解决库存溢出问题、进销存系统溢出问题。
session缓存服务器:web集群时作为session缓存服务器。
缓存队列等。
实现分布式锁和分布式信号量
参考链接:(关于一个秒杀系统的实现)
缓存击穿,缓存雪崩问题
redis与menechaed区别
rabbit
消息丢失问题
消息重复投递问题
延迟消息问题
消息阻塞问题
框架
浅谈源码
ioc、aop原理
参考链接:
javabean作用域
page(默认值)
request
session
application
单例如何实现线程安全的
双重检查锁定(double-checked locking)
public class SingleTon {
// 静态实例变量加上volatile
private static volatile SingleTon instance;
// 私有化构造函数
private SingleTon() {}
// 双重检查锁
public static SingleTon getInstance() {
if (instance == null) {
synchronized(SingleTon.class){
if(instance == null){
instance = new SingleTon();
}
}
}
return instance;
}
}
静态内部类实现 单例模式
public class SingleTon {
// 私有化构造函数
private SingleTon() {}
// 利用静态内部类特性实现外部类的单例
private static class SingleTonBuilder {
private static SingleTon singleTon = new SingleTon();
}
public static SingleTon getInstance() {
return SingleTonBuilder.singleTon;
}
public static void main(String[] args) {
SingleTon instance = SingleTon.getInstance();
}
}
过滤器拦截器在你项目中的使用
登录、日志
springMvc实现流程
eurak多节点配置,及服务注册与发现原理
zuul网关和ngnix区别,为啥用zuul
rpc远程调用原理
服务雪崩,错误收集
服务注册及发现原理
全链路测试,以及微服务