V1

如何遍历Map?
map有个entry对象,通过map.entryset()返回
Set<Map.Entry<K,V>>对象 通过iterator方法返回迭代器
遍历迭代器的getKey,getValue方法获取map的k,v值

StringBuffer,StringBulider区别
对字符串进行修改需要用到这2个对象
StringBuffer是线程安全的,效率低
StringBulider是线程不安全的,效率高

String获得索引
如何获取指定字符

  String s="abcde";
  //获取b的索引
  int b = s.indexOf("b");
  //通过索引获取值
  System.out.println(s.charAt(b));
  //字符串倒转
  String s  = "abcde";
  StringBuilder stringBuilder = new StringBuilder(s);
  System.out.println(stringBuilder.reverse());

  //转换成数组
  char[] chars = s.toCharArray();
  StringBuffer stringBuffer = new StringBuffer();
  for (int i = chars.length-1; i >=0; i--) {
      stringBuffer.append(chars[i]);
  }
  System.out.println(stringBuffer);


  String re = "";
  for (int i = 0; i < s.length(); i++) {
      re = s.charAt(i) + re;
  }
  System.out.println(re);


字符串去除空白方法 trim()
字符串变成大小写方法

//转成小写
String s1 = s.toLowerCase();
//转成大写
String s2 = s.toUpperCase();

字符串常用方法

length()
equals(Object anObject)
format()
hashCode()
indexOf(int ch) 
isEmpty() 
replace(char oldChar, char newChar) 

Substring切割字符串方法

  String s="abcde";
  //切割得到cd
  System.out.println(s.substring(2, 4));

线程池实现方法
new ThreadPoolExecutor()
通过调用Executors的静态方法创建线程池

线程池的属性
核心线程数量
线程的最大数量
阻塞队列的长度 有界,无界
临时线程空闲时,存活时间
ThreadFactory 线程工厂
线程拒绝策略
5种状态

死锁
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

避免死锁的方法
一种是用synchronized,一种是用Lock显式锁实现。
信号量

sleep和wait的区别

sleep导致了程序暂停执行指定的时间,让出cpu该其他线程
wait 线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

Bitmaps
存储状态
bit
统计key中1的数量
bitcount key [start end]
对指定key按位进行交并非异或操作
bitop op destkey key1 key2 …

redis
string,hash,list,set,zset(有序集合)

redis主从复制
将master中的数据即使,有效的赋值到slave中
master 写数据,执行写操作将数据自动到slave
slave 读数据,禁止写数据
主从复制的作用
读写分离
负载均衡
故障恢复
数据冗余
高可用基石
工作流程
slave连接master,数据同步到slave,反复同步
1建立连接阶段(准备阶段)
发送指令 slaveof ip port->接收到指令相应对方->保存master的IP和端口->根据保存的信息创建master的socket->周期性发送指令Ping->相应->auth password 认证
设置master地址和端口保存master信息
建立socket连接
发送ping命令
身份验证
发送slave端口信息
主从连接成功

2.数据同步阶段
步骤1:请求同步数据
步骤2:创建RDB同步数据
步骤3:恢复RDB同步数据
步骤4:请求部分同步数据
步骤5:恢复部分数据同步
至此,数据同步完成
在这里插入图片描述3.命令传播阶段

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份
1.从服务器连接主服务器,发送SYNC命令
2.主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令
3.主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令

redis集群哨兵监控

redis 缓存击穿,缓存雪崩,缓存穿透问题

缓存击穿
某个key过期,该key访问量巨大,多个数据请求从服务器压倒redis后均未命中,redis在短时间内发起了大量对 数据库同一数据的访问
解决方案
预先设定
延长过期时间
二级缓存
加锁 性能瓶颈
缓存雪崩 缓存失效,大量请求到达DB,短期时间范围内大量key集中过期
解决方案:
多级缓存架构
检测mysql严重耗时业务进行优化
对缓存调整过期时间 错峰调整
对超热数据使用永久key
加锁

缓存穿透
redis大面积出现未命中
出现非正常URL访问
解决方法
缓存null 对查询结果为null的数据进行缓存设定短时限
白名单 做个bitmaps
布隆过滤器
实时监控
key加密 防灾业务
缓存穿透访问不存在的数据,跳过合法数据redis数据缓存阶段,每次访问数据库,导致对服务器造成压力。

spring事务的传播特性
@Transactional
propagation 属性(事务传播性
REQUIRED 支持当前已经存在的事务,如果还没有事务,就创建一个新事务。 默认属性

  1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启
  2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
  3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
  4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
  5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
  6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
  7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

mysql如何查询相同数据出现2次的数据?
SELECT equipmentName FROM t_equipment GROUP BY equipmentName HAVING count(*) = 2
mysql优化?

mysql索引
使用like关键字的查询语句。在使用like关键字进行查询的查询语句中,如果匹配字符串的第一个字符为"%",索引不会起作用。只有"%"不在第一个位置,索引才会起到作用。
使用模糊查询,”%“在前面的结果,显示索引没有起了作用了的。
使用多列索引的查询语句。mysql可以为多个字段创建索引。一个索引可以包括16个字段。对于多列索引,只有查询条件中使用了这些字段中第1个字段的时候,索引才会被使用。
使用or关键字的查询语句。使用语句的查询条件中只有or关键字,且or前后的两个条件中的列都有索引时,查询中才使用索引。否则,查询将不适用索引。

SQL优化的一般步骤
通过show status命令了解各种SQL的执行频率。
定位执行效率较低的SQL语句-(重点select)
通过explain分析低效率的SQL
确定问题并采取相应的优化措施
SQL语句优化-show参数
MySQL客户端连接成功后,通过使用show [session|global] status 命令可以提供服务器状态信息。其中的session来表示当前的连接的统计结果,global来表示自数据库上次启动至今的统计结果。默认是session级别的。
EXPLAIN关键字

select_type:表示查询的类型。
table:输出结果集的表
type:表示表的连接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引
key_len:索引字段的长度
rows:扫描出的行数(估算的行数)
Extra:执行情况的描述和说明

select_type
PRIMARY :子查询中最外层查询
SUBQUERY : 子查询内层第一个SELECT,结果不依赖于外部查询
DEPENDENT SUBQUERY:子查询内层第一个SELECT,依赖于外部查询
UNION :UNION语句中第二个SELECT开始后面所有SELECT,
SIMPLE:简单的 select 查询,不使用 union 及子查询
UNION :UNION 中的第二个或随后的 select 查询,不依赖于外部查询的结果集
Table 显示这一步所访问数据库中表名称
Type 对表访问方式
ALL: SELECT * FROM emp \G完整的表扫描 通常不好
SELECT * FROM (SELECT * FROM emp WHERE empno = 1) a ;
system:表仅有一行(=系统表)。这是const联接类型的一个特const:表最多有一个匹配行
Possible_keys 该查询可以利用的索引,如果没有任何索引显示 null
Key Mysql 从 Possible_keys 所选择使用索引
Rows 估算出结果集行数
Extra 查询细节信息

mysql回表
如果是通过非主键索引进行查询,select所要获取的字段不能通过非主键索引获取到,需要通过非主键索引获取到的主键,从聚集索引再次查询一遍,获取到所要查询的记录,这个查询的过程就是回表

mysql的乐观锁和悲观锁 如何实现?
乐观锁:默认当修改数据的时候别人不会来改原来的数据,不进行加锁,当更新的时候判断原有的值是否修改过,如果没有改过则更新否则就不更新,适用于读操作频繁,写操作少的时候
悲观锁:认为修改的时候别人会来修改,所以在修改之前先进行加锁操作,等操作完之后释放锁,这样能保证数据的安全,适用于写操作频繁的时候
如何实现乐观锁?
当我们更新的时候,同时更新数据的版本+1,并判断当前版本是否是查询到的版本,如果不是则判断失败,导致更新数据失败,进行循环更新数据 或者递归实现

volatile关键字
保证线程可见性
java内存模型 当线程执行 会从主内存将共享变量的值拷贝的线程的工作内存进行执行,这样就会存在共享变量的值和工作内存中的不一致,例如某个线程修改了共享变量的值但是其他线程无法感知,volatile中存在缓存一致性协议会降其他工作内存中的值设置失效,这样其他工作内存就会去主内存中读取共享变量的值
禁止重排序

synchronized作用
保证原子性 锁机制
保证可见性 Lock原子操作,会让工作内存去刷新共享变量的数据
保证有序性 依然会发生重排序,我们有同步代码块,可以保证只有一个线程执行同步代码块中的代码,保证有序性
可重入 一个线程可以多次执行synchronized,重复获取同一把锁
原理 锁对象有一个计数器会记录线程获得几次锁
1.避免死锁
2.更好的封装代码
不可中断特性
一个线程获得锁后,另一个线程获得锁必须处于阻塞或等待状态,如果第一个线程不释放锁,第二个线程会一直阻塞或等待,不可被中断

在这里插入图片描述
java对象头由什么组成
markword
klasspoint 指针 存放内存地址
对象头 实例数据 对齐填充
对对象进行加锁 其实就是修改对象的markword的值
2个bit记录锁
1.无状态 new出来的时候
2.偏向锁
3.自旋锁 轻量锁
4.重量锁
5.gc标记

是一条指令 C++处理
重入次数必须记录,解锁几次对应
偏向锁 线程栈 LR+1
自旋锁:消耗cpu资源.自旋线程过多会占用大量cpu
重量级锁 对象Monitor字段上 有等待队列,所有拿不到锁的进入等待队列,不需要消耗CPU资源
多线程竞争的情况下,偏向锁会涉及锁撤销,应该直接使用自旋锁

lock是接口 而且需要释放锁,遇到异常时不会自动释放锁
lock的trylock是可以被中断的
Lock和synchronized的区别
Lock是接口,synchronized是关键字
synchronized执行调用monitorenter加锁monitorexit释放锁,无需自己手动释放,而Lcok需要自己手动释放锁
synchronized是不可中断的,而lock可以中断也可以不中断
通过Lock可以知道线程是否拿到锁,而synchronized不行
synchronized可以锁方法也可以锁代码块,lock只能锁代码块
Lock可以使用读锁提高多线程读效率
synchronized是非公平锁,lock可以控制是否是公平锁

ThreadLocal
ThreadLocal和Synchronized都是为了解决多线程中相同变量的访问冲突问题,不同的点是
Synchronized是通过线程等待,牺牲时间来解决访问冲突
ThreadLocal是通过每个线程单独一份存储空间,牺牲空间来解决冲突,并且相比于Synchronized,ThreadLocal具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问到想要的值。
ThreadLocal 每个线程中都有自己独立的ThreadLocalMap缓存局部变量 当调用set方法的时候,底层使用Entry对象设置key弱引用指向就是为当前线程的ThreadLocal对象
ThreadLocal的静态内部类ThreadLocalMap为每个Thread都维护了一个数组table,ThreadLocal确定了一个数组下标,而这个下标就是value存储的对应位置

抽象类和普通类的区别
普通类中不能包含抽象方法,可以被实例化
抽象类不能被实例化,不能含有finnal最终方法和static静态方法,但是能包含普通方法。抽象类的子类如果不是抽象类,那么必须重写父类的抽象方法。

IO流分为字符流和字节流,根据流向分为输入流和输出流
字节流 读取二进制字节文件,能够读取所有类型的文件,包括图片视频
字符流 字符流通常处理文本数据,它支持写入及读取Unicode码元,处理单元2个字节的Unicode字符

缓冲流 :
字节缓冲流:BufferedInputStream,BufferedOutputStream
给基本流增加一个缓冲区(数组)提高基本的字节输入流的读取效率
字符缓冲流:BufferedReader,BufferedWriter

输入流 读取文件加载到内存中使用
输出流 将文件写入到硬盘中

队列?

消息队列中,如何保证消息的顺序性?

延时加载

redis五种数据类型的用途

Bean的生命周期??
1.实例化一个bean
2.属性注入
3.初始化
4.销毁

1、实例化一个Bean--也就是我们常说的new;
2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;

3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。
9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

List底层结构是数组

HashMap底层数据结构
JDK 数组+链表+红黑树
之前数组+链表
红黑树:高效的查找算法数据结构 特殊的二叉查找树

需要排序时用到TreeMap
HashMap

线程不安全
ArrayList 基于 数组实现
遍历效率高,增删效率低
LinkList 基于双向链表实现
遍历效率低,增删效率高
线程安全的list
collection.synchronizedList 创建
synchronizedList synchronized操作
new CopyOnWriteArrayList lock操作

Hash碰撞如何处理

索引
虽然索引大大提高了查询速度,同时却会降低更新表的速度

什么时候推荐使用索引?

频繁作为查询条件的字段应该建立索引
查询中与其他表关联的字段,外键关系建立索引
查询中排序的字段,排序字段若通过索引去访问将大大提高排序效率
查询中统计或者分组字段

什么时候不建议使用索引?
表记录少的
经常增删改的表或者字段
where条件里用不到的字段不创建索引
过滤性不好的不适合建索引

mysql的varchar和char字段有啥区别?
varchar不是定长,长度会根据传入值的大小而改变 效率相当于char低
char是定长,长度固定,传入的值如果没有char字符的长度 填补空格 效率高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值