一些面试题

限流器

固定窗口,滑动窗口,漏桶(阻塞队列),令牌桶(算数和时间差实现)

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

在排队

服务挂了

动态内存与静态内存的区别

  1. 静态内存

静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源。

程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会

自动释放所占用的内存空间。

变量的分配与释放,都无须程序员自行考虑。

eg:

基本类型,数组

  1. 动态内存

用户无法确定空间大小,或者空间太大,栈上无法分配时,会采用动态内存分配。

  1. 区别

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时,是不一样的。

目标是提高使用者的开发效率

范围查询是否走索引

  1. 假如where条件中,涉及到了多个索引,MySQL会选择一个最佳索引。最佳索引就是选择性最高的索引,因为它可以过滤掉很多的无用数据行。
  2. 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处理大小端

不太懂

regedit打开注册表


   转载规则


《一些面试题》 锦泉 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录