Java面试题整理

一、Java基础



1. String类为什么是final的。
        最佳答案:主要是为了“效率”和“安全性”的缘故。如String允许被继承,由于它的高度被实用性,可能会降低程序的性能,所有String被定义成final。

2. HashMap的源码,实现原理,底层结构。

3. 说说你知道的几个Java集合类:list、set、queue、map实现类咯。。。

4. 描述一下ArrayList和LinkedList各自实现和区别
     参考: http://www.importnew.com/6629.html 

5. Java中的队列都有哪些,有什么区别。
种类:普通队列、阻塞队列、非阻塞队列
区别:
(1)阻塞队列与普通队列区别在于,当队列是空时,从队列中获取元素的操作将被阻塞,或者当队列满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新的元素的线程同样会被阻塞,知道其他的线程使得队列重新变的空闲起来,如从队列中溢出一个或多个元素,或者完全情况队列。
 举例说明:阻塞队列(LinkedBlockingQueue)和非阻塞队列(ConcurrentLinkedQueue)的区别
    相同点:二者都是线程安全的。
    不同点:
         (1)阻塞队列:按FIFO排序元素。队列的头部是在队列中时间最长的元素。队列的尾部是在队列中最短的元素。新元素插入队列的尾部,并且队列检索操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知性能要低。
          注意:A:必须要使用take()方法获取的时候达成阻塞结果
                    B:使用poll()方法产生非阻塞效果
         (2)非阻塞队列:基于链接节点的、无界的、线程安全。按FIFO排序元素。队列的头部是在队列中时间最长的元素。队列的尾部是在队列中最短的元素。新元素插入队列的尾部,并且队列检索操作会获得位于队列头部的元素。当许多线程共享访问一个公共Collection时,ConcurrentLinkedQueue是一个恰当的选择。 此队列不允许为null元素
         (3)在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量避免程序出现意外错误。阻塞队列使用最经典的场景就是socket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。只要符合生产者-消费者模型的都可以使用阻塞队列。
        (4)使用非阻塞队列,虽然能即时返回结果(消费结果),但是必须自行编码解决返回为空的情况(以及消费重试等问题)。

6. 反射中,Class.forName和classloader的区别
     都可以用来对类进行加载。Class.forName不但将类.class文件加载到jvm中之外,还会对类进行解释执行类中的static块。而classloader只是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance时才会去执行static块。
     对比两者具体的执行过程:
     (1)LoadClass()方法加载类及其初始化过程:
          类加载---》newInstance() (链接+初始化)
          newInstance():
         (开始连接)静态代码块-->普通变量分配准备(a=0;b=0;c=null)-->(开始初始化)普通变量赋值(a=1;b=2;c='haha')-->构造方法-->初始化成功
     (2)Class.forName(String className)一个参数方法加载类及其初始化过程:
          类加载--->静态代码块-->newInstance() (链接+初始化)
  newInstance():
         (开始连接)普通变量分配准备(a=0;b=0;c=null)-->(开始初始化)普通变量赋值(a=1;b=2;c='haha')-->构造方法-->初始化成功

     JVM加载类及其初始化过程:
     (1)类加载:Boostrap Loader(启动类加载器)-->Extened Loader(扩展类加载器)-->System Loader(系统加载器)
     (2)静态代码块初始化
     (3)链接:A:验证:是否符合java规范 B:准备:静态变量默认初始值 C:解析:符号引用转为直接引用,解析地址
     (4)初始化:A:赋值,真正的初始化,用户给变量赋予的值 B:构造方法

7. Java7、Java8的新特性(baidu问的,好BT)
     Java7的新特性:
       (1)语法上:
               A:二进制变量的标示,支持将整数类型用二进制来标示,用0b开头。
               B:Switch语句支持String类型
               C:Try-witch-resource语句
               D:Catch多个异常(catch异常类型为final)
               E:数字类型的下划线标示,更友好的表达式
               F: 泛型实例的创建可以通过类型推断来简化 可以去掉后面 new 部分的泛型类型,只用<>就可以了。
        G: 在可变参数方法中传递非具体化参数,改进编译警告和错误
        H: 信息更丰富的回溯追踪 就是上面 try try 语句和里面的语句同时抛出异常时,异常栈的信息
    Java8的新特性
          (1)接口的默认方法:允许给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫扩展方法。
              
          (2)Lambda表达式
            
     
            
          (3)函数式接口:仅仅只包含一个抽象对象的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。只需给接口添加@FunctionalInterface注释,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。
            
            
          (4)方法与构造函数引用:允许你使用::关键字来传递方法或者构造函数引用,以下代码展示了如何引用一个静态方法。
            
             构造函数引用:
            
              
          (5)lambda作用域:
               在lambda表达式中访问外层作用域和老版本的匿名对象中的方式相似,你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。
          (6)访问局部变量
               
          (7)访问对象字段与静态变量
               和本地变量不同的是,lambda内部对于实例的字段以及静态变量是既可读又可写的。
            
          (8)访问接口的默认方法
          (9)Date API
               Clock时钟:提供了访问当前日期和时间方法。java.time.Clock
          (10)Annotation注解:支持多种注解
      

8. Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高

9. Java内存泄露的问题调查定位:jmap,jstack的使用等等

10. string、stringbuilder、stringbuffer区别

11. hashtable和hashmap的区别

13 .异常的结构,运行时异常和非运行时异常,各举个例子

14. String a= “abc” String b = "abc" String c = new String("abc") String d = "ab" + "c" .他们之间用 == 比较的结果


15. String 类的常用方法

16. Java 的引用类型有哪几种
     强引用、软引用、弱引用、虚引用

17. 抽象类和接口的区别

18. java的基础类型和字节大小。

19. Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题(建议熟悉 jdk 源码,才能从容应答)

20. 如果不让你用Java Jdk提供的工具,你自己实现一个Map,你怎么做。说了好久,说了HashMap源代码,如果我做,就会借鉴HashMap的原理,说了一通HashMap实现

21. Hash冲突怎么办?哪些解决散列冲突的方法?

22. HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提升到log(n)咯,用二叉排序树的思路说了一通
          理解了hashmap的实现,聪明的人肯定已经知道怎么更加高性能的使用hashmap。不过在此之前还是先说明下初始容量和负载因子的含义。 
          Hashmap的设想是在O(1)的时间复杂度存取数据,根据我们的分析,在最坏情况下,时间复杂度很可能是o(n),但这肯定极少出现。但是某个链表中存在多个元素还是有相当大的可能的。当hashmap中的元素数量越接近数组长度,这个几率就越大。为了保证hashmap的性能,我们对元素数量/数组长度的值做了上限,此值就是负载因子。当比值大于负载因子时,就需要对内置数组进行扩容,从而提高读写性能。但这也正是问题的所在,对数组扩容,代价较大,时间复杂度时O(n)。    
          故我们在hashmap需要存放的元素数量可以预估的情况下,预先设定一个初始容量,来避免自动扩容的操作来提高性能。  

23. rehash

24. hashCode() 与 equals() 生成算法、方法怎么重写

二、Java IO



1. 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。

2. 讲讲NIO。
     参考: http://blog.jobbole.com/88984/

3. String 编码UTF-8 和GBK的区别?

4. 什么时候使用字节流、什么时候使用字符流?

5. 递归读取文件夹下的文件,代码怎么实现

三、Java Web


1. session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。

2. servlet的一些相关问题

3. webservice相关问题

4. jdbc连接,forname方式的步骤,怎么声明使用一个事务。举例并具体代码

5. 无框架下配置web.xml的主要配置内容

6. jsp和servlet的区别

四、JVM



1. Java的内存模型以及GC算法

2. jvm性能调优都做了什么
     
     JVM性能调优有很多设置,这个参考JVM参数即可.
     主要调优的目的:
    1. 控制GC的行为.GC是一个后台处理,但是它也是会消耗系统性能的,因此经常会根据系统运行的程序的特性来更改GC行为
    2. 控制JVM堆栈大小.一般来说,JVM在内存分配上不需要你修改,(举例)但是当你的程序新生代对象在某个时间段产生的比较多的时候,就需要控制新生代的堆大小.同时,还要需要控制总的JVM大小避免内存溢出
    3. 控制JVM线程的内存分配.如果是多线程程序,产生线程和线程运行所消耗的内存也是可以控制的,需要通过一定时间的观测后,配置最优结果

3. 介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明

4. 介绍GC 和GC Root不正常引用。

5. 自己从classload 加载方式,加载机制说开去,从程序运行时数据区,讲到内存分配,讲到String常量池,讲到JVM垃圾回收机制,算法,hotspot。反正就是各种扩展
     程序运行数据区: http://www.cnblogs.com/lrh-xl/p/5277585.html
     内存分配:      http://javawebsoa.iteye.com/blog/1558776

6. jvm 如何分配直接内存, new 对象如何不分配在堆而是栈上,常量池解析

7. 数组多大放在 JVM 老年代(不只是设置 PretenureSizeThreshold ,问通常多大,没做过一问便知)     

8. 老年代中数组的访问方式
     
9. GC 算法,永久代对象如何 GC , GC 有环怎么处理
     

针对HotSpot VM的实现,它里面的GC其实准确分类只有两大种:

  • Partial GC:并不收集整个GC堆的模式
    • Young GC:只收集young gen的GC
    • Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式
    • Mixed GC:收集整个young gen以及部分old gen的GC。只有G1有这个模式
  • Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

Major GC通常是跟full GC是等价的,收集整个GC堆。但因为HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了,当有人说“major GC”的时候一定要问清楚他想要指的是上面的full GC还是old gen。

最简单的分代式GC策略,按HotSpot VM的serial GC的实现来看,触发条件是:

  • young GC:当young gen中的eden区分配满的时候触发。注意young GC中有部分存活对象会晋升到old gen,所以young GC后old gen的占用量通常会有所升高。
  • full GC:当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC);或者,如果有perm gen的话,要在perm gen分配空间但已经没有足够空间时,也要触发一次full GC;或者System.gc()、heap dump带GC,默认也是触发full GC。

HotSpot VM里其它非并发GC的触发条件复杂一些,不过大致的原理与上面说的其实一样。
当然也总有例外。Parallel Scavenge(-XX:+UseParallelGC)框架下,默认是在要触发full GC前先执行一次young GC,并且两次GC之间能让应用程序稍微运行一小下,以期降低full GC的暂停时间(因为young GC会尽量清理了young gen的死对象,减少了full GC的工作量)。这是HotSpot VM里的奇葩嗯。

并发GC的触发条件就不太一样。以CMS GC为例,它主要是定时去检查old gen的使用量,当使用量超过了触发比例就会启动一次CMS GC,对old gen做并发收集。(RednaxelaFX——知乎)

Java的GC原理不是引用计数,所以即使有环,只要他是从GC Root不可达的,同样也会被收集。

10. 谁会被 GC ,什么时候 GC
      程序认为的死去的对象,也就是不可达对象会被GC。

11. 如果想不被 GC 怎么办
     不被GC,创建对象的强引用,并一直不释放

12. 如果想在 GC 中生存 1 次怎么办
     生存一次,释放掉对象的引用,但是在对象的finalize方法中重新建立引用,但是有一此方法只会被调用一次,所以能在GC中生存一次

13.如何在JVM虚拟机挂掉的时候,做一些操作,例如发邮件通知
     可以使用Runtime里面的addShutdownHook(Thread hook)方法,把JVM挂掉的时候所需要启动的线程注册到runtime中,就可以帮你完成这个动作
     

五、开源框架



1. hibernate和ibatis的区别
     
  1. hibernate 是当前最流行的o/r mapping框架,它出身于sf.net,现在已经成为jboss的一部分了。  
  2. ibatis 是另外一种优秀的o/r mapping框架,目前属于apache的一个子项目了。   
  3. 相对hibernate“o/r”而言,ibatis是一种“sql mapping”的orm实现。   
  4. hibernate对数据库结构提供了较为完整的封装,hibernate的o/r mapping实现了pojo 和数据库表之间的映射,以及sql 的自动生成和执行。程序员往往只需定义好了pojo 到数据库表的映射关系,即可通过hibernate 提供的方法完成持久层操作。程序员甚至不需要对sql 的熟练掌握, hibernate/ojb 会根据制定的存储逻辑,自动生成对应的sql 并调用jdbc 接口加以执行。   
  5. 而ibatis 的着力点,则在于pojo 与sql之间的映射关系。也就是说,ibatis并不会为程序员在运行期自动生成sql 执行。具体的sql 需要程序员编写,然后通过映射配置文件,将sql所需的参数,以及返回的结果字段映射到指定pojo。   
  6. 使用ibatis 提供的orm机制,对业务逻辑实现人员而言,面对的是纯粹的java对象。  
  7. 这一层与通过hibernate 实现orm 而言基本一致,而对于具体的数据操作,hibernate会自动生成sql 语句,而ibatis 则要求开发者编写具体的sql 语句。相对hibernate而言,ibatis 以sql开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。   
  8. hibernate与ibatis的对比:  
  9. 1.ibatis非常简单易学,hibernate相对较复杂,门槛较高。   
  10. 2.二者都是比较优秀的开源产品   
  11. 3.当系统属于二次开发,无法对数据库结构做到控制和修改,那ibatis的灵活性将比hibernate更适合   
  12. 4.系统数据处理量巨大,性能要求极为苛刻,这往往意味着我们必须通过经过高度优化的sql语句(或存储过程)才能达到系统性能设计指标。在这种情况下ibatis会有更好的可控性和表现。   
  13. 5.ibatis需要手写sql语句,也可以生成一部分,hibernate则基本上可以自动生成,偶尔会写一些hql。同样的需求,ibatis的工作量比hibernate要大很多。类似的,如果涉及到数据库字段的修改,hibernate修改的地方很少,而ibatis要把那些sql mapping的地方一一修改。   
  14. 6.以数据库字段一一对应映射得到的po和hibernte这种对象化映射得到的po是截然不同的,本质区别在于这种po是扁平化的,不像hibernate映射的po是可以表达立体的对象继承,聚合等等关系的,这将会直接影响到你的整个软件系统的设计思路。   
  15. 7.hibernate现在已经是主流o/r mapping框架,从文档的丰富性,产品的完善性,版本的开发速度都要强于ibatis。  

2. 讲讲mybatis的连接池。
     参考: http://www.tuicool.com/articles/RvqEjeR   

3. spring框架中需要引用哪些jar包,以及这些jar包的用途

4. springMVC的原理

5. springMVC注解的意思

6. spring中beanFactory和ApplicationContext的联系和区别
  1. 作用:  
  2.   
  3. 1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。  
  4. 2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:  
  5.   
  6. a. 国际化支持  
  7. b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”  
  8. c. 事件传递:通过实现ApplicationContextAware接口  
  9. 3. 常用的获取ApplicationContext的方法:  
  10. FileSystemXmlApplicationContext:从文件系统或者url指定的xml配置文件创建,参数为配置文件名或文件名数组  
  11. ClassPathXmlApplicationContext:从classpath的xml配置文件创建,可以从jar包中读取配置文件  
  12. WebApplicationContextUtils:从web应用的根目录读取配置文件,需要先在web.xml中配置,可以配置监听器或者servlet来实现  
  13. <listener>  
  14. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  15. </listener>  
  16. <servlet>  
  17. <servlet-name>context</servlet-name>  
  18. <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>  
  19. <load-on-startup>1</load-on-startup>  
  20. </servlet>  
  21. 这两种方式都默认配置文件为web-inf/applicationContext.xml,也可使用context-param指定配置文件  
  22. <context-param>  
  23. <param-name>contextConfigLocation</param-name>  
  24. <param-value>/WEB-INF/myApplicationContext.xml</param-value>  
  25. </context-param>  
7. spring注入的几种方式(循环注入)

8. spring如何实现事物管理的

9. springIOC

10. spring AOP的原理

11. hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)
     参考: http://www.jb51.net/article/75161.htm   

12. Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理。

六、多线程



1. Java创建线程之后,直接调用start()方法和run()的区别

2. 常用的线程池模式以及不同线程池的使用场景

3. newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理。

4. 多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响。

5. 了解可重入锁的含义,以及ReentrantLock 和synchronized的区别

6. 同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高

7. atomicinteger和volatile等线程安全操作的关键字的理解和使用

8. 线程间通信,wait和notify
     参考: http://www.jb51.net/article/40746.htm   

9. 定时线程的使用

10. 场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。

11. 进程和线程的区别

12. 什么叫线程安全?举例说明
     
  1. 线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题  

13. 线程的几种状态

14. 并发、同步的接口或方法
     
  1. 1:线程池  
  2.   
  3.    与每次需要时都创建线程相比,线程池可以降低创建线程的开销,这也是因为线程池在线程执行结束后进行的是回收操作,而不是真正的  
  4.   
  5.  销毁线程。  
  6.   
  7. 2:ReentrantLock  
  8.   
  9.     ReentrantLock提供了tryLock方法,tryLock调用的时候,如果锁被其他线程持有,那么tryLock会立即返回,返回结果为false,如果锁没有被  
  10.   
  11. 其他线程持有,那么当前调用线程会持有锁,并且tryLock返回的结果是true,  
  12.   
  13.   lock.lock();  
  14.   
  15.   try {  
  16.   
  17.       //do something   
  18.   
  19.   } finally {  
  20.   
  21.       lock.unlock();  
  22.   
  23.    }  
  24.   
  25. 3volatile  
  26.   
  27.      保证了同一个变量在多线程中的可见性,所以它更多是用于修饰作为开关状态的变量,因为volatile保证了只有一份主存中的数据。  
  28.   
  29. 4:Atomics  
  30.   
  31.        public class Count {  
  32.   
  33.             private AtomicInteger counter = new AtomicInteger();  
  34.   
  35.            public int increase() {  
  36.   
  37.                 return counter.incrementAndGet();  
  38.   
  39.            }  
  40.   
  41.           public int decrease() {  
  42.   
  43.                return counter.decrementAndGet();  
  44.   
  45.           }  
  46.   
  47.       }  
  48.   
  49.  AtomicInteger内部通过JNI的方式使用了硬件支持的CAS指令。  
  50.   
  51. 5:CountDownLatch  
  52.   
  53.       它是java.util.concurrent包中的一个类,它主要提供的机制是当多个(具体数量等于初始化CountDown时的count参数的值)线程都到达了预期状态  
  54.   
  55. 或完成预期工作时触发事件,其他线程可以等待这个事件来出发自己后续的工作,等待的线程可以是多个,即CountDownLatch是可以唤醒多个等待  
  56.   
  57. 的线程的,到达自己预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法  
  58.   
  59. 6:CyclicBarrier  
  60.     循环屏障,CyclicBarrier可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都到达了这个屏障时,再一起继续执行后面的动作。  
  61.    CyclicBarrier和CountDownLatch都是用于多个线程间的协调的,二者的一个很大的差别是,CountDownLatch是在多个线程都进行了latch.countDown  
  62. 后才会触发事件,唤醒await在latch上的线程,而执行countDown的线程,执行完countDown后,会继续自己线程的工作;  
  63.    CyclicBarrier是一个栅栏,用于同步所有调用await方法的线程,并且等所有线程都到了await方法,这些线程才一起返回继续各自的工作,因为使用CyclicBarrier的线程都会阻塞在await方法上,所以在线程池中使用CyclicBarrier时要特别小心,如果线程池的线程 数过少,那么就会发生死锁了,  
  64. CyclicBarrier可以循环使用,CountDownLatch不能循环使用。  
  65. 7:Semaphore  
  66.    是用于管理信号量的,构造的时候传入可供管理的信号量的数值,信号量对量管理的信号就像令牌,构造时传入个数,总数就是控制并发的数量。  
  67.     semaphore.acquire();  
  68.     try {  
  69.         //调用远程通信的方法 
  70.     } finally () {    
  71.        semahore.release();  
  72.     }  
  73. 8:Exchanger  
  74.    Exchanger,从名字上讲就是交换,它用于在两个线程之间进行数据交换,线程会阻塞在Exchanger的exchange方法上,直到另一个线程也到了   
  75. 同一个Exchanger的exchange方法时,二者进行交换,然后两个线程会继续执行自身相关的代码。  
  76. 9:Future和FutureTask  
  77.   
  78.    Future<HashMap> future = getDataFromRemote2();  
  79.   
  80.    //do something  
  81.   
  82.    HashMap data = (HashMap)future.get();  
  83.   
  84.     
  85.   
  86.   private Future<HashMap> getDateFromRemote2() {  
  87.   
  88.       return threadPool.submit(new Callable<HashMap>() {  
  89.   
  90.             public HashMap call() {  
  91.   
  92.                    return getDataFromRemote();  
  93.             }  
  94.       });  
  95.   }  
  96.   
  97. 思路:调用函数后马上返回,然后继续向下执行,急需要数据时再来用,或者说再来等待这个数据,具体实现方式有两种,一个是用Future,另一个使用回调。  
     

15. HashMap 是否线程安全,为何不安全。 ConcurrentHashMap,线程安全,为何安全。底层实现是怎么样的。

16. J.U.C下的常见类的使用。 ThreadPool的深入考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现。

17. 简单介绍下多线程的情况,从建立一个线程开始。然后怎么控制同步过程,多线程常用的方法和结构

18. volatile的理解

19. 实现多线程有几种方式,多线程同步怎么做,说说几个线程里常用的方法
                   http://blog.csdn.net/you_off3/article/details/7572704   
    

七、网络通信



1. http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。

2. socket通信,以及长连接,分包,连接异常断开的处理。

3. socket通信模型的使用,AIO和NIO。
     参考:AIO: http://www.52im.net/thread-306-1-1.html 
               NIO: http://www.cnblogs.com/dolphin0520/p/3916526.html 

4. socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。
              

5. 同步和异步,阻塞和非阻塞。

6. OSI七层模型,包括TCP,IP的一些基本知识

7. http中,get post的区别

8. 说说http,tcp,udp之间关系和区别。

9. 说说浏览器访问www.taobao.com,经历了怎样的过程。

10. HTTP协议、  HTTPS协议,SSL协议及完整交互过程;

11. tcp的拥塞,快回传,ip的报文丢弃

12. https处理的一个过程,对称加密和非对称加密

13. head各个特点和区别
     参考:

八、数据库MySql


1. MySql的存储引擎的不同

2. 单个索引、联合索引、主键索引
     

3. Mysql怎么分表,以及分表后如果想按条件分页查询怎么办(如果不是按分表字段来查询的话,几乎效率低下,无解)

1)、做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

优点:扩展性好,没有多个分表后的复杂操作(php代码)

缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大。

2)、预先估计会出现大数据量并且访问频繁的表,将其分为若干个表

优点:避免一张表出现几百万条数据,缩短了一条sql的执行时间

缺点:当一种规则确定时,打破这条规则会很麻烦,上面的例子中我用的hash算法是crc32,如果我现在不想用这个算法了,改用md5后,会使同一个用户的消息被存储到不同的表中,这样数

据乱套了。扩展性很差。

3)、利用merge存储引擎来实现分表

优点:扩展性好,并且程序代码改动的不是很大

缺点:这种方法的效果比第二种要差一点

4. 分表之后想让一个id多个表是自增的,效率实现

5. MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离

6. 写SQL语句。。。


7. 索引的数据结构,B+树

MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等

MySQL就普遍使用B+Tree实现其索引结构

8. 事务的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些问题

9. 数据库的锁:行锁,表锁;乐观锁,悲观锁
     

mysql中有一种机制是表锁定和行锁定,为什么要出现这种机制,是为了保证数据的完整性

举个例子来说吧,如果有二个sql都要修改同一张表的同一条数据,这个时候怎么办呢,是不是二个sql都可以同时修改这条数据呢?

很显然mysql对这种情况的处理是,一种是表锁定(myisam存储引擎),一个是行锁定(innodb存储引擎)。

表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定一样

10. 数据库事务的几种粒度;
     数据库级、表级、记录级(行级)和属性级(字段级)

11.  关系型和非关系型数据库区别

12.数据库的隔离级别:

脏读: 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一

个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第

一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

九、设计模式



1. 单例模式:饱汉、饿汉。以及饿汉中的延迟加载,双重检查

2. 工厂模式、装饰者模式、观察者模式。

3. 工厂方法模式的优点(低耦合、高内聚,开放封闭原则)

十、算法



1. 使用随机算法产生一个数,要求把1-1000W之间这些数全部生成。(考察高效率,解决产生冲突的问题)

2. 两个有序数组的合并排序

3. 一个数组的倒序

4. 计算一个正整数的正平方根

5. 说白了就是常见的那些查找、排序算法以及各自的时间复杂度

6. 二叉树的遍历算法

7. DFS,BFS算法

9. 比较重要的数据结构,如链表,队列,栈的基本理解及大致实现。

10. 排序算法与时空复杂度(快排为什么不稳定,为什么你的项目还在用)

11. 逆波兰计算器

12. Hoffman 编码

13. 查找树与红黑树
     

十一、并发与性能调优



1. 有个每秒钟5k个请求,查询手机号所属地的笔试题(记得不完整,没列出),如何设计算法?请求再多,比如5w,如何设计整个系统?


2. 高并发情况下,我们系统是如何支撑大量的请求的

认清系统的高并发由3个层面导致:

1. 传输层

大量用户对系统请求后,将会造成网络带宽和Web服务器的I/O瓶颈。

2. 计算层

接收大量用户请求进行计算,将会造成业务服务器和业务支撑服务器的瓶颈。

3. 存储层

传输层和计算层将会产生大量的数据,数据量暴增,将会导致数据库和储存上的瓶颈。

高并发的解决方法有两种,一种是使用缓存、另一种是使用生成静态页面

1.用分布式应用设计2、分布式缓存数据库3、代码优化。

1.不要频繁的new对象,对于在整个应用中只需要存在一个实例的类使用单例模式.对于String的连接操作,使用StringBuffer或者

StringBuilder.对于utility类型的类通过静态方法来访问。

2. 避免使用错误的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace消耗性能,除非必要不要使用 instanceof做条件判

断,尽量使用比的条件判断方式.使用JAVA中效率高的类,比如ArrayList比Vector性能好。)

3、使用静态页面

补充: 页面静态化

3. 集群如何同步会话状态

4. 负载均衡的原理

5 .如果有一个特别大的访问量,到数据库上,怎么做优化(DB设计,DBIO,SQL优化,Java优化)

6. 如果出现大面积并发,在不增加服务器的基础上,如何解决服务器响应不及时问题“。

7. 假如你的项目出现性能瓶颈了,你觉得可能会是哪些方面,怎么解决问题。
     

8. 如何查找 造成 性能瓶颈出现的位置,是哪个位置照成性能瓶颈。

9. 你的项目中使用过缓存机制吗?有没用用户非本地缓存
     

十二、其他


1.常用的linux下的命令

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值