2019秋招百度与阿里二面面经难点总结1

(1) java中内存泄露有几种?如何分析泄露原因

具体主要有如下几大类:
1、静态集合类引起内存泄露: 像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。 例: Static Vector v = new Vector(10); for (int i = 1; i<100; i++) { Object o = new Object(); v.add(o); o = null; }// 在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身(o=null),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。 例: public static void main(String[] args) { Set set = new HashSet(); Person p1 = new Person(“唐僧”,“pwd1”,25); Person p2 = new Person(“孙悟空”,“pwd2”,26); Person p3 = new Person(“猪八戒”,“pwd3”,27); set.add(p1); set.add(p2); set.add(p3); System.out.println(“总共有:”+set.size()+" 个元素!"); //结果:总共有:3 个元素! p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变 set.remove(p3); //此时remove不掉,造成内存泄漏 set.add(p3); //重新添加,居然添加成功 System.out.println(“总共有:”+set.size()+" 个元素!"); //结果:总共有:4 个元素! for (Person person : set) { System.out.println(person); } }

3、监听器 在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

4、各种连接 比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。

5、内部类和外部模块等的引用 内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法如: public void registerMsg(Object b); 这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。

6、单例模式 不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子: class A{ public A(){ B.getInstance().setA(this); } … } //B类采用单例模式 class B{ private A a; private static B instance=new B(); public B(){} public static B getInstance(){ return instance; } public void setA(A a){ this.a=a; } //getter… } 显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较复杂的对象或者集合类型会发生。

(2)Mybatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
 
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

(3) 模糊查询like语句该怎么写?

第1种:在Java代码中添加sql通配符。

string wildcardname =%smi%;
list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”>
 select * from foo where bar like #{value}
</select>

第2种:在sql语句中拼接通配符,会引起sql注入

string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”>
     select * from foo where bar like "%"#{value}"%"
</select>

(3)数据库中为什么不推荐使用外键约束

电商项目中数据库表不推荐外键关联,但是在被关联表中删除数据时会导致关联表中经常出现数据缺失的问题,但如果在删除数据时在业务层删除数据做关联查询来判断是否被关联使用,会导致业务层逻辑复杂,特别是被多个业务表关联,会导致多次关联查询操作,后面每次增加一个业务关联都得增加一次判断。
解决方案:
可以在关联表中增加一个被关联次数的字段,每次关联时都加1,每次取消关联都减一。

(4)能简单介绍下您现在所做项目和过程中的技术难点或有遇到瓶颈吗?

要点:
1.痛点:解决的问题,用户痛点 2.正确性 3.可用性
4.大规模:量级 5.思考问题:宏观,不局限于业务

我说的是高并发分布式场景的数据一致性问题

(5)说下什么是一致性哈希?

推荐一遍优质博文比较详细讲解
传送门
一致性Hash算法

(6)说说项目中遇到的难点和你怎么解决的吧

说到了大文件的存储问题,一开始存储到存储到数据库,但会导致表的体积变大,使查询缓慢。就改为用线程池实现生产者消费者队列通过io存到本地的文件中,然后在数据库中存储文件路径。由于服务器的内存很小,之后压测的时候发现当较多用户同时存储大文件时会占用大量的内存。现在的想法是增加一个前端服务器,实现前后端分离,把一些静态文件存到前端,通过前端服务器的反向代理把请求发到后端,后端只保存信息数据。

(7)一条sql语句的执行过程

当时瞬间懵逼

给大家看个图理解吧,不过我说的并不全,要想看详细的还得传送门
在这里插入图片描述
放大招、传送门

面试必备:一条sql语句的执行过程

(8)说下进程间的通信方式吧

1.管道:速度慢,容量有限,只有父子进程能通讯

2.FIFO:任何进程间都能通讯,但速度慢

3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题

4.信号量:不能传递复杂消息,只能用来同步

5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

(9)如果服务器在运行中cpu突然暴增怎么排查

首先通过ps命令查看一下占用cpu最多的进程,再根据请求选择是否要杀死它还是用其他的解决方案。

然后通过stack工具打印Java的方法栈,查看是否有死锁的存在。

然后通过其他排查工具定位问题所在。如果是数据库连接的的问题,就用回滚策略解决。如果只是单纯的请求量暴增导致的,那么就先重启服务,并在以后的开发中多进行压测。

(10)想做一个线程安全的计数器,怎么做

用AtomicInteger做,它底层使用的是Unsafe包中的方法,使用的是CAS操作来对数据进行修改。CAS是Java中一种轻量级锁的实现,它在操作之前要判断目标对象是否处于一个理想值,如果是则进行操作,如果不是就不会进行操作。在多线程的环境下,如果线程B对计数器做了修改,线程A在修改计数器时发现计数器已经不是自己理想的状态了,就不会再把错误的值写入了,这样就能保证计数器计数的准确性。

未完待续…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tronhon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值