Java常规面试题

1. Java进程消耗CPU过高:

      通过top 命令找到消耗CPU最高的进程,通过grep -mp pid -o Thread, tid, time 找到进程下面最消耗CPU的时间的线程

      找到线程的转换成16进制 prinf "%x\n" tid, 然后用jstack  pid |grep 十六进制的tid

2. Java常用的命令

     jmap 查看堆内存使用情况。

   jmap -heap pid查看进程堆内存使用情况

      jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图

   jmap -dump:format=b,file=dumpFileName pid

3.JDK原子操作的原理

  原子操作的变量声明为volatile,保证变量的读取和操作是一致的,同时提供getAndIncrement方法,这个方法封装变量的++操作,提供了compareAndSet方法。来完成对单个变量的加锁以及解锁.Auto基于Unsafe方法全名为:sun.misc.Unsafe包含了大量的对C代码的操作。Unsafe实现了compareAndSetInt之类的原子操作方法。

CompareAndSet原子操作的原理是如果当前值==预期值,则已原子方式更新给定的值

CAS的原子性实际上是CPU实现的.

3. String为什么是不可变的

   String的实现类中包好private final char[] value value的值是final的所以是不可变的~


4. Set : 存入Set的每个元素都必须是唯一的, Set的底层使用Map来实现的

5.  HashMap:Map基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能

6. 线程问题的排查:

   Jstack查看线程的运行信息。

   jstat提供一些统计信息,包含当前的GC情况,GC次数,时间,对VM内存使用量进行监控

   jstat -gc pid显示gc的信息,jstat -class pid 显示加载的class的数量,占用的空间,jstat -gccapacity 显示VM内存三代对象的使用和占用大

  jmap输出内存中对象的工具

7 Mysql:

  Mysql的集群主要包含以下几种方式:

  常规复制架构:Master-slavers:一个Master复制到一个或者多个salve模式,主要用户读压力大的有那个用数据实现读写分离

  级联复制架构: Master-slaves-slaves,为了防止slaves的读压力大二配置二级slaves.解决Master附属太多slaver而成为瓶颈的风险

  Dual Master与级联复制结构结构: Master-Master-Slaver.最大的好处是既可以避免主Master的写操作收到slaver集群复制带来的影响,以及保证主Masterde单点故障

 Mysql的存储引擎

  MYISAM,不支持事物,也不支持外键,但是其访问速度快,是事物完整性没有要求。

  InnoDB 他提供了事物,行级锁和外键约束

  Memory存储引擎使用内存的内容创建表。速度非常快但是关闭服务表中的数据就会丢失

8 Java的序列化

   当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量, 如果一个对象的成员变量是一个对象,      那么这个对象的数据成员也会被保存。 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛  出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。对于父类的处理,如果父类没有实现序列化接口,则必须有默认的构造函数。否则编译的时候会出错。在反序列化的时候,默认构造函数会被调用。如果实现则默认构造函数不会被调用。因为反序列化不是通过其构造函数来完成的

   ObjectOutput接口 (序列化里面特别重要的一个接口) ,ObjectOutput继承DataOutput. ObjectOutStream继承OutputStream实现了Objectout

9 对于多线程开发,比较大的挑战有哪些

   程序的设计更加复杂,尤其涉及到多线程共享数据的时候~

10 如何避免出现数据不一致导致死锁得问题

1.一次性封锁法,要求每个事物必须要将所有使用的数据全部加锁,否则不能继续执行

         2.顺序封锁法, 原先对数据对象规定一个封锁顺序,所有事物必须按照这个顺序实行封锁

11 秒杀的解决办法

      前端:扩容,静态化,限流,有损服务。

      后端:Mysql禁止死锁检测提供并发性、

      解决方案1:从Mysql迁移到Redis, Redis是基于内存的,性能远高于Mysql,通过队列等异步手段,将变化的数据异步写入到DB

     解决方案2:

       引入队列,然后将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候就不在消费队列,并关闭购买功能。这就解决了超卖问题。

        优点:解决超卖问题,略微提升性能。 缺点:性能受限于队列处理机处理性能和DB的写入性能中最短的那个,另外多商品同时抢购的时候需要准备多条队列。

   解决方案3:

        将写操作前移到MC中,同时利用MC的轻量级的锁机制CAS来实现减库存操作。

        优点:读写在内存中,操作性能快,引入轻量级锁之后可以保证同一时刻只有一个写入成功,解决减库存问题。

        缺点:没有实测,基于CAS的特性不知道高并发下是否会出现大量更新失败?不过加锁之后肯定对并发性能会有影响。

12. JVM调优的目的:

在保证正常服务的前提下,GC尽可能的少,GC执行的时间尽可能短,FUll GC的间隔尽可能长。前两着是相悖的。

        1JVM堆一般设置成相同的值,避免堆的收缩产生额外的时间,

        2.年轻带和年老带的比例默认是3;8 通过NewRatio来调整两者大小,也可以通过-XX:newSize -XX:MaxNewSize,年老带和年轻带是调优的关键点。

            A、更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC

             B、更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率

            C、如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性,在抉择时应该根据以下两点:a、本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例3:8也是这个道理(B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响FullGC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间。

13. Spring的IOC的配置方式:

1.属性注入:

<property name="helloservice"><ref bean = "helloService"></propoty>

2.构造器注入:

<constructor-arg><ref bean = "helloService"></constructor-arg>

        3.静态工厂注入:

<bean id="helleAction" class="org.yoo.helloAction" factory-method = "createInstance">

<constructor-arg><ref bean = "helloService"></construcor-arg>

Action中增加静态方法createInstance

        4.注解模式:

必须引入:AutowiredAnnotationBeanPostProcessor

        5.实例工厂:

<bean id="bean4" factory-bean = "beanfacotoy" factory-method="newInstance">


14.BeanFacory的时序图:

AbstractApplicationCotent 通过 obtanFreshBeanFacotry 调用AbstractRefreshableApplicationContent的refreshBeanFacory

       AbstractRefreshableApplicationContent的refreshBeanFacory调用CreateBeanFacoty创建DefalutListableBeanFacoty.

       同时调用loadBeanDefinitions()加载Resource LoadBeanDefinitions从AbstractXmlApplicationsContext实例化XmlBeanDefinaitonReader.

15. BeanDefinnation的加载过程:

XmlBeanDefination 调用InputSource读取Resource.同时调用registerBeanDefinitons创建BeanDefinitionDocumentReader ,最终通过BeanDefinationRegistor注册到到facoty中。

16. Bean创建的流程

17. Bean的组装AbstractbeanFacoty调用createBean createbean调用AbstractAutowireCapableBeanfacoty的doCreateBean.调用instantiatebean

18.Spring的扩展点:

1.AbstractApplicationContent中的invokeBeanFacoryPostProcess获取实现BeanFactoryPostProcessor接口的子类,并且执行postProcessorBeanfacoty方法。

         2.registerBeanPostProcessors 方法获得用户定义的BeanPostProcessor,并且将他们注册到Beanfacory的beanPostProcessor变量中。BeanPostProcessor声明了两个方法:postProcessBeforInitiallizaiton, postProcessAfterInitialization方法。

19.springAoP实现的原理 ProxyFactoryBean封装链接器链,生产JdkDynamicAopProxy.Spring创建了代理对象之后,就可以调用目标对象上的方法时。将会代理到InvocationHandler类的invoke方法。

20. springAOP注解:

  <aop:aspectj-autoproxy />  

  <context:component-scan base-package="com.aop"/> 

21.常用的推荐算法:

   1 基于人口统计学的推荐

   2.基于内容的推荐

   3.协同过滤


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值