限流器
固定窗口,滑动窗口,漏桶(阻塞队列),令牌桶(算数和时间差实现)
https://cloud.tencent.com/developer/article/1165247
快排,归并,堆排序一定要会写
ArrayList和LinkedList的区别
底层是基于动态数组,初始容量为10,达到当前上限 + 1时才扩容,根据下标随机访问数组元素的效率高,向数组尾部添加元素的效率高;但是,删除数组中的数据以及向数组中间添加数据效率低,因为需要移动数组。例如最坏的情况是删除第一个数组元素,则需要将第2至第n个数组元素各向前移动一位。
而之所以称为动态数组,是因为Arraylist在数组元素超过其容量大,Arraylist可以进行扩容(针对JDK1.8 数组扩容后的容量是扩容前的1.5倍),Arraylist源码中最大的数组容量是Integer.MAX_VALUE-8,对于空出的8位,目前解释是 :①存储Headerwords;②避免一些机器内存溢出,减少出错几率,所以少分配③最大还是能支持到Integer.MAX_VALUE(当Integer.MAX_VALUE-8依旧无法满足需求时)。
大端将高位存放在低地址,记住大端才是符合人类正常思维!
HashMap的put过程,存null怎么存
前面那个for循环,是在table[0]链表中查找key为null的元素,如果找到,则将value重新赋值给这个元素的value,并返回原来的value。
如果上面for循环没找到则将这个元素添加到talbe[0]链表的表头。
利用sql语句统计各年龄段的数量
SELECT age_temp,COUNT(*) AS total FROM (
SELECT age,
CASE
WHEN age BETWEEN 10 AND 20 THEN '10-20'
WHEN age BETWEEN 20 AND 30 THEN '20-30'
END AS age_temp
FROM t_user
)AS temp_table GROUP BY age_temp;
字段查重
-- 只对一个字段查重,只有PLAN_NUMBER这一列结果
SELECT DISTINCT PLAN_NUMBER FROM psur_list;
-- 对多个字段去重,只有选了多个字段的结果
SELECT DISTINCT PLAN_NUMBER,PRODUCT_NAME FROM psur_list;
期望结果:只对第一个参数PLAN_NUMBER取唯一值,可以显示其他字段
解决办法一: 使用 group_concat 函数
SELECT GROUP_CONCAT(DISTINCT PLAN_NUMBER) AS PLAN_NUMBER,PRODUCT_NAME FROM psur_list GROUP BY PLAN_NUMBER
解决办法二:使用group by
SELECT PLAN_NUMBER,PRODUCT_NAME FROM psur_list GROUP BY PLAN_NUMBER
六、Linux相关命令。查看日志中某一个时间点之后的日志信息?
grep '时间' '日志文件名'
八、虚拟内存和物理内存讨论?
当每个进程创建的时候,内核会为进程分配4G的虚拟内存,当进程还没有开始运行时,这只是一个内存布局。实际上并不立即就把虚拟内存对应位置的程序数据和代码(比如.text .data段)拷贝到物理内存中,只是建立好虚拟内存和磁盘文件之间的映射就好(叫做存储器映射)。这个时候数据和代码还是在磁盘上的。当运行到对应的程序时,进程去寻找页表,发现页表中地址没有存放在物理内存上,而是在磁盘上,于是发生缺页异常,于是将磁盘上的数据拷贝到物理内存中。
另外在进程运行过程中,要通过malloc来动态分配内存时,也只是分配了虚拟内存,即为这块虚拟内存对应的页表项做相应设置,当进程真正访问到此数据时,才引发缺页异常。
可以认为虚拟空间都被映射到了磁盘空间中(事实上也是按需要映射到磁盘空间上,通过mmap,mmap是用来建立虚拟空间和磁盘空间的映射关系的)
协程,是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。协程在子程序内部是可中断的,然后转而执行别的子程序,在适当的时候再返回来接着执行。
访问者模式
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下,定义作用于这些元素的新操作。
String的两种初始化方法的一点区别
String str=new String(“XXX”);
String str=”XXX”;
前者是java中标准的对象创建方式,其创建的对象将直接放置到堆中,每调用一次就会在堆上面创建一个新的对象;后者则会在栈中创建一个对象引用变量str,然后查看字符串池中是否存在”XXX”,如果没有,则将”XXX”存放字符串池,并令引用变量str指向它;如果已经有”XXX”,则直接令str指向它。这样充分利用了栈的数据共享优点,当然也可能是一个陷阱,对象很有可能没有创建,只不过指向一个先前已经创建的对象;而new()
方法则能保证每次都指向新创建象。
避免内存泄漏、溢出的几种常用方法
尽早释放无用对象的引用
程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer
尽量少用静态变量
因为静态变量是全局的,GC不会回收
避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作
JVM会突然需要大量内存,这时会触发GC优化系统内存环境; 一个案例如下:
// 使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误,
// 检查之后发现问题:组件里的代码
m_totalBytes = m_request.getContentLength();
m_binArray = new byte[m_totalBytes];
totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。
// 解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。
尽量运用对象池技术以提高系统性能
生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。
可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。
优化配置
- 设置-Xms、-Xmx相等;
- 设置NewSize、MaxNewSize相等;
- 设置Heap size, PermGen space;
Exception vs Error
Exception:可以预见到的异常情况,应该被捕获或者处理,分为IOException和RuntimeException
Error:出现乐错误系统不能正常运行或恢复,一般情况不容易发送
调用api阻塞,怎么处理?
死锁
被拦截了
读从库时在执行sql
在排队
服务挂了
动态内存与静态内存的区别
- 静态内存
静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源。
程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会
自动释放所占用的内存空间。
变量的分配与释放,都无须程序员自行考虑。
eg:
基本类型,数组
- 动态内存
用户无法确定空间大小,或者空间太大,栈上无法分配时,会采用动态内存分配。
- 区别
a) 静态内存分配在编译时完成,不占用CPU资源; 动态内存分配在运行时,分配与释放都占用CPU资源。
b) 静态内存在栈上分配; 动态内存在堆上分配。
c) 动态内存分配需要指针和引用类型支持,静态不需要。
d) 静态内存分配是按计划分配,由编译器负责; 动态内存分配是按需分配,由程序员负责。
Spring和SpringBoot区别
Spring包含SpringBoot
SpringBoot的核心能力:
1、内嵌 Servlet 容器,可以直接打成jar包,通过 java -jar xx.jar 运行项目。
2、提供 starter pom 系列,简化maven的依赖加载,减少依赖冲突的发生。
3、支持自动化配置,如下图。application.properties 文件在引入springboot和未引入springboot时,是不一样的。
目标是提高使用者的开发效率
范围查询是否走索引
- 假如where条件中,涉及到了多个索引,MySQL会选择一个最佳索引。最佳索引就是选择性最高的索引,因为它可以过滤掉很多的无用数据行。
- 0.30比例值。以前可能是>0.30就不走索引,但文档最低版本是5.6已无从考证。
并不是给一个列建立了索引,对这个列进行范围查询的时候,就会走索引,他是有一个比例值的。比例值会随着版本、服务器、IO、数据量、数据重复情况而不同。也就是说,同一个版本,同一个库表,此时和下一时刻,比例值就可能不一样。测试中途遇到过该问题。
MySQL5.6版本的时候,进行了优化,ICP 和 MRR,极大提升性能。
FORCE INDEX 的作用,特殊情况下,可以只返回索引列。
https://juejin.cn/post/6864150089905274893
数据库的dml、ddl和dcl的概念
DML就是我们经常用到的SELECT、INSERT、UPDATE和DELETE语句
DDL就是我们在创建表的时候用到的一些语句,比如说CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构、数据类型、表之间的链接或约束等初始化工作上。
DCL是用来设置或更改数据库用户或角色权限的语句,包括GRANT、DENY、REVOKE等语句,这个层面应该主要是DBA做的事情了,但是如果是在小公司可能你还是要干,像部署数据库的时候你不会怎么行,特别是ORACLE这种用户驱动的数据库。
mysql大数据分页查询优化
基于索引再排序
SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M
mysql大数据量使用limit分页,随着页码的增大,查询效率越低下
对limit分页问题的性能优化方法
利用表的覆盖索引来加速分页查询:我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。
因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。
在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。
//这次我们之间查询最后一页的数据(利用覆盖索引,只包含id列),如下:
select id from product limit 866613, 20 0.2秒
//相对于查询了所有列的37.44秒,提升了大概100多倍的速度
//那么如果我们也要查询所有列,有两种方法,
//一种是id>=的形式,
//另一种就是利用join,看下实际情况:
SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
//查询时间为0.2秒!
//另一种写法
SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id
//查询时间也很短!
1024*768的24位真彩色BMP图像至少需要多大存储空间
1024*768*24/8/1024/1024=2.25MB
RGB三管道,每个管道8bit
线程从阻塞到就绪的方式
线程从阻塞状态恢复到就绪状态,有三种途径:自动恢复、用resume()
方法恢复,notify方法恢复
netty处理大小端
不太懂