Java常用功能

1. arraylist


transient Object[] elementData 【writeObject已经序列号过】
扩容机制: 
Arrays.copyof(elementData,newCapacity) -> System.arraycopy()
init 10, oldCapacity + oldCapacity>>1 = 1.5倍
remove():判空,for循环 fastRemove
和LinkedList区别:底层数据结构不用,一个基于数组,一个基于链表。arraylist更适合随机查找

2. hashmap


Node<K,V>
resize(): new Node<K,V> 默认16(1<<4) 双倍扩容 2的n次:为了保证高位都是0,低位都是1,如果传13,会计算返回16
putVal(int hash,K key, V value, boolean onlyIfAbsent, boolean evict)
    tab[i = (n -1) & hash]: 不可能越界,下标和hash算法有关 &位运算比%求余(底层是除法,减法)性能更好
h:  0101 0101
15: 0001 1111
  & 0000 0101
数组+链表+红黑树
数组:先算下标,数组的长度大于64才会去转红黑树,小于64先对数组扩容。红黑树不需要扩容
链表:9个节点的时候,会转成红黑树,未插入前就已经有8个节点了。9个节点转红黑树比红黑树在加节点性能

3. == 与 equals


==:如果基本数据类型,比较值,如果是引用类型,比较引用地址
equals:具体要看各个类重写equals方法后的比较逻辑,String虽然是引用类型,但重写了。先比较引用地址,然后比较每个字符是否相等。 Object底层的equals就是==

4. mysql


1)线上慢sql如何优化
建索引,why:相当于一本书的目录,能快速定位磁盘位置,减少磁盘IO,可能一次就能定位到
减少不必要的join,放java处理:表关联底层算法,多表关联,一旦表数据量达到很大量级,会很慢

二叉树:1-7,会变成一个链表
红黑树:二叉平衡树,会往右边一直加,树的高度几十万
B树:叶节点
B+Tree和B树的区别:1.非叶子节点不存储data,只存储索引(冗余) 2.叶子节点包含所有索引字段,存储data(从左到右依次递增),3:叶子节点用双向指针连接,提高区间访问的性能
树的高度<=4,磁盘页Innodb_page_size:16384,16KB   Bigint:8Byte , 16KB/8Byte+6byte = 1170, 叶子节点data算1KB,树高度为3:1170*1170*16 = 2千万。 
索引默认存储磁盘位置:mysql/data/一个库对应一个文件夹/test_myisam.三个文件

存储引擎:修饰数据库表的,非库
MyISAM:索引文件和数据文件是分离的,非聚集索引
test_myisam.frm:表结构文件
test_myisam.MYD:d表示data
test_myisam.MYI: I表示index

InnoDB:
test_innodb_lock.frm:表结构
test_innodb_lock.ibd:数据和索引放一起,聚集索引

为什么建议innodb表必须建主键,并且推荐使用整形的自增主键
如果不建主键,会自动找一列当主键,如果找不到会自动维护隐藏列
整形比较大小,比uuid要快,存储空间比uuid要小, 自增只会往最后面加,如果是uuid可能会往中间插,叶子节点会分裂,树平衡影响效率
主键索引:primary key, 叶子节点会存整行数据,非主键索引叶子节点存的是主键,回表操作

哈希索引:仅能满足= in,不支持范围查询,性能比B+tree更高效
b+tree,叶子节点有双向指针,能支持范围查询【排好序的数据结构】

联合索引(a,b,c),最左前缀法则:a, ab, abc都会走索引,不带a则不会, ac呢?
explain
explain extended
show warnings;
explain partitions
type列:此列表示关联类型或访问类型。也就是MySQL决定如何查找表中的行。依次从最优到最差分别为:system > const > eq_ref > ref > range > index > all
system、const:MySQL对查询的某部分进行优化并把其转化成一个常量(可以通过show warnings命令查看结果)。system是const的一个特例,表示表里只有一条元组匹配时为system
 eq_ref:主键或唯一键索引被连接使用,最多只会返回一条符合条件的记录
   ref:相比eq_ref,不使用唯一索引,而是使用普通索引或者唯一索引的部分前缀,索引和某个值比较,会找到多个符合条件的行。
range:通常出现在范围查询中,比如in、between、大于、小于等。使用索引来检索给定范围的行。
 index:扫描全索引拿到结果,一般是扫描某个二级索引,二级索引一般比较少,所以通常比ALL快一点。
  ALL:全表扫描,扫描聚簇索引的所有叶子节点。

rows列:此列是MySQL在查询中估计要读取的行数。注意这里不是结果集的行数

事务四大特性:
原子性:undo log日志保证
一致性:使用事务的最终目的,由业务代码保证
隔离性
持久性:redo log日志文件,磁盘顺序写,提升写的性能。ibd文件不能磁盘顺序写(一个表一个文件,redolog日志是共用一个文件)

默认隔离级别:由mysql的各种锁以及MVVC机制来实现
read uncommited读未提交:脏读,a线程还没提交的事务,b线程能查到a修改的结果,但a可能回滚
read commited读已提交:不可重复读, 本来是100,a线程修改成500,b线程改成600,c线程两次查询的结果500,600 【语句级快照】
repeatable-read可重复读:脏写, 本来是100,a线程改成了500,但b线程查的还是100。 提升了性能,降低了一致性【事务级快照】
串行:多个事务操作同一条数据,会阻塞,读和写串行执行,直到事务提交

ru,rc,rr

innodb引擎:可重复读
oracle默认隔离级别:

读锁(共享锁,S锁):select ... lock in share mode;
读锁是共享,多个事务可以同时读取同一个资源,但不允许其他事务修改
写锁(排他锁,X锁):select ... for update;
写锁是排他的,会阻塞其他的写锁和读锁,update/insert/delete都会加锁

MVVC:多版本并发机制,做到读写不阻塞,undo日志链,记录多个版本。 
mvvc导致的脏写问题解决方案:
乐观锁:版本号,或者where 带上某些字段。更新失败,可以while再查询一次
用sql: update account  set balance = balance + 500 where id = 1; balance如果是select是快照,如果是update是最新的数据

查询操作方法:需要使用事务吗
rc:适合互联网to c的服务
rr: 后台报表服务,需要加事务,这样就能控制查同一版本状态下的数据,如果不加事务,只会查最新的数据。但是可能会回滚

大事务的影响
并发情况下,数据库连接池容易被撑爆
容易死锁
执行时间长,容易导致主从延迟

mysql索引失效
数据类型不匹配:例如,如果索引列是varchar类型,而查询条件是数字类型,MySQL会将索引列转换为数字类型进行比较,这样就无法使用索引了
模糊查询以%开头:因为以%开头的模糊匹配无法确定索引列的起始位置,所以无法利用索引进行快速查找
索引列使用了函数或运算:因为函数或运算会改变索引列的值,使得原来的索引无法使用
索引列包含空值。如果索引列中包含空值(NULL),那么在查询条件中使用IS NULL或IS NOT NULL也会导致索引失效,因为MySQL在建立索引时不会存储空值,所以无法通过索引来判断是否为空
查询条件中使用了OR关键字,因为MySQL无法同时使用多个索引来进行查询优化,所以只能选择全表扫描
联合索引违反了最左前缀原则

mysq 执行顺序
FROM子句-》WHERE子句-》GROUP BY子句-》HAVING子句-》SELECT子句-》ORDER BY子句-》LIMIT子句


5. 多线程


JMM内存模型
线程1 工作内存 共享主内存
线程2 工作内存 共享主内存

原子操作
read(读取):从主内存读取数据
load
use
assign
store
write


缓存一致性协议
总线嗅探机制


volatile:多线程可见性底层原理,保证了可见性、有序性,但不能保证原子性
底层实现主要是通过汇编lock前缀
1. 会将当前处理器缓存行的数据 立即 写回到系统内存
2. 写回的操作,会引起其他线程,失效该数据,重新从主内存read
3. 提供内存屏障,使得lock前后指令不能重排序

并发编程三大特性
可见性、有序性、原子性

单例模式:双重检测锁
public class A{
    private static A a = null;
    private A(){

    }
    public static A getA(){
        if(a == null){
            synchronized(A.class){
                if(a == null){
                    a = new A();
                }
            }
        }
        return a;
    }
}
上面存在一个问题:a = new A(); 会存在指令重排序
对象半初始化问题
解决:加volatile


spring


初始化:
implements InitializingBean -> @Override afterPropertiesSet()  
@postconstruct

生命周期
class -> 推断构造方法 -》 实例化-》 对象1 -》属性填充-》 初始化afterPropertiesSet()-> AOP-》 代理对象->bean

单例bean: 一个类,名字不同,可以是不同的对象

构造函数:推断构造方法
1. 没有无参构造器时,如果有多个有参构造器,会报错,如果只有一个则不会
2. 如果在有参构造器上@AutoWired,则会用这个
public UserService(OrderService orderService, OrderService orderService1){
    //先根据类型找,再根据名称找。如果有orderService 1,2,3三个对象,则orderService4会报错
}


@AutoWired:方法注入点、属性注入点 先根据type找到多个,中间会有过滤操作,比如autowired=false, @Primary, @Priority(1),最后根据name确定一个
@Resource:java层面注解,如果定义了名字,则直接根据名字找。先根据名字去找,如果找不到则根据类型找,如果找到多个则会报错


spring事务
代理逻辑
1. 建立数据库连接
2. conn.setAutoCommit(false)
3. 业务逻辑
4. commit

事务失效场景
1. 同一个类,方法自调用(放到另外一个bean或者自己注入自己)
2. 方法被private、final修饰。aop,不能重写父类
3. 多线程
4. trycatch


redis
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值