面试

Java基础


● Java是如何支持正则表达式操作的?

答:
String类支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作,如:

 

import java.util.regex.Matcher;
import java.util.regex.Pattern;
class RegExpTest {
    public static void main(String[] args) {
        String str = "成都市(成华区)(武侯区)(高新区)";
        Pattern p = Pattern.compile(".*?(?=\\()");
        Matcher m = p.matcher(str);
        if(m.find()) {
            System.out.println(m.group());
        }
    }
}



● 正则表达式及其用途。
答:
在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是记录文本规则的代码。计算机处理的信息更多的时候不是数值而是字符串,正则表达式就是在进行字符串匹配和处理的时候最为强大的工具,绝大多数语言都提供了对正则表达式的支持。

● 比较Java和JavaSciprt?
答:
Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。


● &和&&的区别?


答:
&有两种用法:(1)按位与;(2)逻辑与。

&&是短路与运算。

二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。逻辑与跟短路与的差别是:如果&&左边的表达式的值是false,右边的表达式不会进行运算。

很多时候是用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。


● int和Integer有什么区别?


答:
自动装箱/拆箱机制,int和Integer可以相互转换。
Java 为每个原始类型提供了包装类型:
- 原始类型: boolean,char,byte,short,int,long,float,double
- 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

● 如何输出一个某种编码的字符串(如iso8859-1)
答:

Public String translate (String str) {
 String tempStr = “”;
 try {
     tempStr = new String(str.getBytes(“ISO-8859-1″), “GBK”);
     tempStr = tempStr.trim();
  }
  catch (Exception e) {
     System.err.println(e.getMessage());
  }
 return tempStr;
}




● 基本数据类型?
答:
基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。

 

 

● 数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?

答:

1、Array对象的初始化必须指定大小,且创建后的数组大小是固定的;而ArrayList的大小可以动态指定;

2、Array始终是连续存放的;而ArrayList的存放不一定连续;

4、Array不能随意添加、删除;而ArrayList提供了更多的方法,如:addAll(),removeAll(),iterator()。

Array->ArrayList:

int size=list.size();

String[] array = (String[])list.toArray(new String[size]);

 

ArrayList->Array:

List<String> list=Arrays.asList(array);

 

 

 

● 为什么重写equals还要重写hashcode?

答:

HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两个对象,比较也是不相等的。HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等。重载hashCode()是为了对同一个key,能得到相同的Hash Code,这样HashMap就可以定位到我们指定的key上。重载equals()是为了向HashMap表明当前对象和key上所保存的对象是相等的,这样我们才真正地获得了这个key所对应的这个键值对。

 

● map的分类

 

答:

HashMap Hashtable LinkedHashMap 和TreeMap.

 

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历时,先得到的记录肯定是先插入的。

 


● final
答:
final修饰的类为最终类,不能被继承,final修饰的方法不能被重写

● 请你谈谈关于Synchronized和lock 
答:
synchronized关键字修饰一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行该段代码。Lock是一个接口,synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

 

请你介绍一下volatile?

答:

volatile关键字是用来保证有序性和可见性的。对一个变量的写操作先行发生于后面对这个变量的读操作;有序性实现的是通过插入内存屏障来保证的。可见性:首先Java内存模型分为,主内存,工作内存。比如线程A从主内存把变量从主内存读到了自己的工作内存中,做了加1的操作,但是此时没有将i的最新值刷新会主内存中,线程B此时读到的还是i的旧值。加了volatile关键字的代码生成的汇编代码发现,会多出一个lock前缀指令。Lock指令对Intel平台的CPU,早期是锁总线,这样代价太高了,后面提出了缓存一致性协议,MESI,来保证了多核之间数据不一致性问题。




● 若对一个类不重写,它的equals()方法是如何比较的?
答:
比较是对象的地址。

 


 



● 什么是构造函数?什么是构造函数重载?什么是复制构造函数?
答:
当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。若程序员没有提供构造函数,Java编译器会创建一个默认的构造函数。 一个类可以创建多个构造函数,但每一个构造函数必须有它自己唯一的参数列表。 



● 方法覆盖/重写(Overriding)和方法重载(Overloading)是什么意思?
答:

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

重载:方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。(名称相同,参数不同)

覆盖:方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。(名称相同,返回类型相同,参数相同,访问权限≥父类,抛出异常≦父类)

 


● 请说明Query接口的list方法和iterate方法有什么区别?
答:
①list()方法无法利用一级缓存和二级缓存(对缓存只写不读),它只能在开启查询缓存的前提下使用查询缓存;iterate()方法可以充分利用缓存,如果目标数据只读或者读取频繁,使用iterate()方法可以减少性能开销。
② list()方法不会引起N+1查询问题,而iterate()方法可能引起N+1查询问题


● 请说明如何通过反射获取和设置对象私有字段的值?
答:
可以通过类对象的getDeclaredField()方法字段(Field)对象,然后再通过字段对象的setAccessible(true)将其设置为可以访问,接下来就可以通过get/set方法来获取/设置字段的值了。下面的代码实现了一个反射的工具类,其中的两个静态方法分别用于获取和设置私有字段的值,字段可以是基本类型也可以是对象类型且支持多级对象操作,例如ReflectionUtil.get(dog, "owner.car.engine.id");可以获得dog对象的主人的汽车的引擎的ID号。

import java.lang.reflect.Method;
class MethodInvokeTest 

{
  public static void main(String[] args) throws Exception 

{
    String str = "hello";
    Method m = str.getClass().getMethod("toUpperCase");
    System.out.println(m.invoke(str));  // HELLO
  }
}


● 两个对象值相同(x.equals(y) == true),但却可有不同的hashcode,该说法是否正确?

答:
不对,对象x和y满足x.equals(y) == true,它们的哈希码应当相同。

  1. 如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;

(2)如果两个对象的hashCode相同,它们并不一定相同。



● 请说明内部类可以引用他包含类的成员吗,如果可以,有没有什么限制吗?
答:
一个内部类对象可以访问创建它的外部类对象的内容,内部类如果不是static的,那么它可以访问创建它的外部类对象的所有属性内部类如果是static的,即为nested class,那么它只可以访问创建它的外部类对象的所有static属性一般普通类只有public或package的访问修饰,而内部类可以实现static,protected,private等访问修饰。当从外部类继承的时候,内部类是不会被覆盖的,它们是完全独立的实体,每个都在自己的命名空间内,如果从内部类中明确地继承,就可以覆盖原来内部类的方法。
 

● 如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
答:
用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。Finally为确保一段代码不管发生什么”异常”都被执行一段代码。



● 请你说说Static Nested Class 和 Inner Class的不同

答:
Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。Static-Nested Class 的成员, 既可以定义为静态的(static), 也可以定义为动态的(instance).Nested Class的静态成员(Method)只能对Outer Class的静态成员(static memebr)进行操作(ACCESS), 而不能Access Outer Class的动态成员(instance member).而 Nested Class的动态成员(instance method) 却可以 Access Outer Class的所有成员, 这个概念很重要, 许多人对这个概念模糊. 有一个普通的原则, 因为静态方法(static method) 总是跟 CLASS 相关联(bind CLASS), 而动态方法( (instance method) 总是跟 instance object 相关联, 所以,静态方法(static method)永远不可以Access跟 object 相关的动态成员(instance member),反过来就可以, 一个CLASS的 instance object 可以 Access 这个 Class 的任何成员, 包括静态成员(static member).

 

public class GenericTest {
 
      public static void main(String[] args) {
          /*
          List list = new ArrayList();
          list.add("qqyumidi");
          list.add("corn");
          list.add(100);
          */
 
         List<String> list = new ArrayList<String>();
         list.add("qqyumidi");
         list.add("corn");
         //list.add(100);   // 1  提示编译错误
 
         for (int i = 0; i < list.size(); i++) {
             String name = list.get(i); // 2
             System.out.println("name:" + name);
         }
     }
 }
采用泛型写法后,在//1处想加入一个Integer类型的对象时会出现编译错误,通过List<String>,直接限定了list集合中只能含有String类型的元素,从而在//2处无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。

 

● 请说明静态变量存在什么位置?

答:方法区

 

 

● 请你解释一下类加载机制,双亲委派模型,好处是什么?

答:

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

 

使用双亲委派模型的好处在于Java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类java.lang.Object,它存在在rt.jar中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的Bootstrap ClassLoader进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果没有双亲委派模型而是由各个类加载器自行加载的话,如果用户编写了一个java.lang.Object的同名类并放在ClassPath中,那系统中将会出现多个不同的Object类,程序将混乱。因此,如果开发者尝试编写一个与rt.jar类库中重名的Java类,可以正常编译,但是永远无法被加载运行。

 

 

请你谈谈StringBuffer和StringBuilder有什么区别?

答:

StringBuffer线程安全,StringBuilder线程不安全,StringBuffer其实就是比StringBuilder多了Synchronized修饰符。

 

 

 

 

 Object类的方法。

答:

Object()默认构造方法。

clone() 创建并返回此对象的一个副本。

equals(Object obj) 指示某个其他对象是否与此对象“相等”。

finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

getClass()返回一个对象的运行时类。

hashCode()返回该对象的哈希码值。 notify()唤醒在此对象监视器上等待的单个线程。

notifyAll()唤醒在此对象监视器上等待的所有线程。

toString()返回该对象的字符串表示。

wait()导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。

 

 

 

● Java有哪些特性,并举一个和多态有关的例子。

答:

封装、继承、多态。

多态:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

 

 

 

 

请解释一下TreeMap?

答:

TreeMap是一个有序的key-value集合,基于红黑树(Red-Black tree)的 NavigableMap实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序,具体取决于使用的构造方法。

TreeMap的特性:

根节点是黑色

每个节点都只能是红色或者黑色

每个叶节点(NIL节点,空节点)是黑色的。

如果一个节点是红色的,则它两个子节点都是黑色的,也就是说在一条路径上不能出现两个红色的节点。

从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

 

 

 

 

● 请你说明一下TreeMap的底层实现?

考点:集合

 

答:

TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。

 

红黑树的插入、删除、遍历时间复杂度都为O(lgN),所以性能上低于哈希表。但是哈希表无法提供键值对的有序输出,红黑树因为是排序插入的,可以按照键的值的大小有序输出。红黑树性质:

 

性质1:每个节点要么是红色,要么是黑色。

 

性质2:根节点永远是黑色的。

 

性质3:所有的叶节点都是空节点(即 null),并且是黑色的。

 

性质4:每个红色节点的两个子节点都是黑色。(从每个叶子到根的路径上不会有两个连续的红色节点)

 

性质5:从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。

 

 

 

 

 请你简单介绍一下ArrayList和LinkedList的区别,并说明如果一直在list的尾部添加元素,用哪种方式的效率高?

答:

ArrayList采用数组数组实现的,查找效率比LinkedList高。

LinkedList采用双向链表实现的,插入和删除的效率比ArrayList要高。

一直在list的尾部添加元素,LinkedList效率要高。

 

 

 

● 如何保证线程安全?
答:
通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以通过适当的策略,保证任务与任务之间不存在共享资源,设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成,而不是把一个客户的计算工作分配给多个线程去完成。

● 请你简要说明一下线程的基本状态以及状态之间的关系?
答:
其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。

 

 

 

 

 

用什么关键字修饰同步方法? 

答:

用synchronized关键字修饰同步方法

 

stop()和suspend()方法为何不推荐使用,请说明原因?
答:
反对使用stop(),是因为它不安全。

suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,

 

若标志指出线程应该挂起,用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

● 请说出你所知道的线程同步的方法
答:
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程。


● 启动一个线程是用run()还是start()?
答:
启动一个线程是调用start()方法,这意味着它可以由JVM调度并执行,但这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

● 请使用内部类实现线程设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。
答:
public class ThreadTest1{
private int j;
public static void main(String args[]){
ThreadTest1 tt=new ThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(int i=0;i<2;i++){
Thread t=new Thread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
public void run(){
for(int i=0;i<100;i++){
inc();
}
}
}
class Dec implements Runnable{
public void run(){
for(int i=0;i<100;i++){
dec();
}
}
}
}

● 请说明一下线程中的同步和异步有何异同?并且请举例说明在什么情况下会使用到同步和异步?
答:
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

● 请说明一下sleep() 和 wait() 有什么区别
答:
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有对象发出notify方法(或notifyAll)后本线程才进入运行状态。

● 请你说明一下在监视器(Monitor)内部,是如何做到线程同步的?在程序又应该做哪种级别的同步呢? 
答:
监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。


线程从创建到死亡的状态?
答:
1.新建(new):新创建了一个线程对象。
2.可运行(runnable):就绪态,万事俱备,只欠CPU。
3.运行(running):运行态,线程获得了cpu时间(timeslice)。
4.阻塞(block):阻塞态,线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。

阻塞的情况分三种:
(一).等待阻塞:运行的线程执行o.wait()方法,JVM会把该线程放入等待 队列(waitting queue)中。
(二).同步阻塞:运行的线程被别的线程占用,则JVM会把该线程放入锁池 (lock pool)中。
(三).其他阻塞:运行的线程执行Thread.sleep(long ms)或t.join()方法, 或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超 时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可 运行(runnable)状态。
5.死亡(dead):线程run()方法执行结束,或者因异常退出了run()方法, 则该线程结束生命周期。

 


● 请解释一下Java多线程回调是什么意思?
答:
所谓回调,就是客户程序C调用服务程序S中的某个方法A,然后S又在某个时候反过来调用C中的某个方法B,对于C来说,这个B便叫做回调方法。


● cyclicbarrier和countdownlatch的区别分别是什么?
答:
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

● 线程池有什么优势?
答:
第一:降低资源消耗。重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能执行。
第三:提高线程的可管理性,使用线程池可以进行统一分配和监控。



● 请回答一下Java中有几种线程池?并且详细描述一下线程池的实现过程
答:
1、newFixedThreadPool创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。 
2、newCachedThreadPool创建一个可缓存的线程池。这种类型的线程池特点是: 
1).工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。 
2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。 

3、newSingleThreadExecutor创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它,保证顺序执行(我觉得这点是它的特色)。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的 。 
4、newScheduleThreadPool创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。(这种线程池原理暂还没完全了解透彻) 

 



● 创建线程的方法,哪个方法更好
答:

继承Thread类

实现Runnable接口
实现Runnalbe接口更好,使用实现Runnable接口的方式创建的线程,可以处理同一资源,从而实现资源的共享.



● 线程,进程,然后线程创建有很大开销,怎么优化?
答:
可以使用线程池。

● 生产者消费者模式?
答:
生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。


● 多线程同步的方法?

答:
可以使用synchronized、lock、volatile和ThreadLocal来实现同步。

● 多线程中的i++线程安全吗?请简述一下原因?
答:
不安全。i++不是原子性操作。i++分为读取i值,对i值加一,再赋值给i++,执行期中任何一步都是有可能被其他线程抢占的

 

反射的实现过程和作用分别是什么?

答:

JAVA语言编译之后会生成.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。以便在程序在运行时能够获取自身的信息。

反射的实现主要借助以下四个类:

Class:类的对象,

Constructor:类的构造方法,

Field:类中的属性对象,

Method:类中的方法对象。

 

● 请简单描述一下JVM加载class文件的原理是什么?
答:
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。

● 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
答:
Java虚拟机是一个可以执行Java字节码的虚拟机进程。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。



● JVM分区?
答:
java内存通常被划分为5个区域:

程序计数器(Program Count Register)、

本地方法栈(Native Stack)、

方法区(Methon Area)、

栈(Stack)、

 

● 运行时异常与受检异常区别?
答:
异常表示程序运行过程中可能出现的非正常状态,

运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。

受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。



● 请问什么是java序列化?以及如何实现java序列化?
答:
序列化:将对象转化为字节流的过程

反序列化:将字节流转化为对象的过程

序列化的实现:类实现serializable接口,这个接口并没有需要实现的方法,实现这个接口主要是为了告诉jvm这个类可以序列化

其他:

某个类可以被序列化那么它的子类也可以被序列化

申明为static 和transient的成员变量不可以被序列化


● 异常处理机制
答:
是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,所有的异常都是 java.lang.Thowable的子类。

● 请问你平时最常见到的runtime exception是什么?
答:
ArithmeticException,

ArrayStoreException,

BufferOverflowException,

BufferUnderflowException,

CannotRedoException,
CannotUndoException,

ClassCastException,

CMMException,

ConcurrentModificationException,

DOMException,
EmptyStackException,

IllegalArgumentException,

IllegalMonitorStateException,

IllegalPathStateException,
IllegalStateException,

ImagingOpException,

IndexOutOfBoundsException,

MissingResourceException,
NegativeArraySizeException,

NoSuchElementException,

NullPointerException,

ProfileDataException,

ProviderException,
RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException,
UnsupportedOperationException

● 请问error和exception有什么区别?
答:
error 不能恢复的严重问题。比如说内存溢出。程序不能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,

 

 

  1. String常用的方法

1.indexOf()返回指定字符索引

2.charAt()返回指定处字符

3.replace()字符串替换

4.trim()去除字符串两端的空白

5.split()分割字符串,返回分割后的字符串数组

6.length()返回字符串长度

7.toLowerCase()将字符串转化为小写字母

8.toUpperCase()将字符串转化为大写字母

9.subString()截取字符串

10.equals()字符串比较

 

  1. java 中 IO 流分为几种

按功能来分:

输入流(input)和输出流(output)

按类型来分:

字节流(8位)与字符流(16位)

 

  1.  JDK 和 JRE 有什么区别?

JDK包含了JRE同时还包含了java源码的编译器javac,如果只运行java程序,只需要安装JRE,如果要编写java程序需要安装JDK

 

  1. ==和equas的区别

 

 

  1.  fina 在 java 中有什么作用?

1.final修饰的类为最终类,不能被继承

2.final修饰的方法不能被重写

 

  •  java 中操作字符串都有哪些类?它们之间有什么区别?

 

 

 

 

● 请说明List、Map、Set三个接口存取元素时,各有什么特点?

 

 

 

● 阐述ArrayList、Vector、LinkedList的存储性能和特性

答:

ArrayList 和Vector是数组存储结构,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。

LinkedList使用双向链表存储结构,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

ArrayList和LinkedList都实现了List接口,都是非线程安全的,Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器。

 

 

● 请说明Collection 和 Collections的区别。

答:

Collection是集合类的上级接口,继承与他的接口主要有Set 和List.

Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

 

 

● 请你说明HashMap和Hashtable的区别?

答:

HashMap和Hashtable都实现了Map接口。

不同点:

HashMap允许键和值是null,而Hashtable不允许键或者值是null。

Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。

 

 

 

● 请你说说Iterator和ListIterator的区别?

答:

Iterator和ListIterator的区别是:

Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。

Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

ListIterator实现了Iterator接口,并包含其他的功能。

 

● 请简单说明一下什么是迭代器?

答:

迭代器用来遍历集合,使用方法iterator()要求容器返回一个Iterator。使用next()获得序列中的下一个元素。使用hasNext()检查序列中是否还有元素。

Iterator iterList= list.iterator();//List接口实现了Iterable接口 
while (iterList.hasNext()){
 String strList=iterList.next();
 System.out.println(strList.toString());
}

 

 

Java web

 


 1分钟之内只能处理1000个请求,你怎么实现?
答:
限流的几种方法:计数器,滑动窗口、漏桶法、令牌桶

 如何在链接里不输入项目名称的情况下启动项目?
答:
可在taomcat配置虚拟目录。

● JSP中的静态包含和动态包含的有哪些区别
答:
<%-- 静态包含 --%>
<%@ include file="..." %>
<%-- 动态包含 --%>
<jsp:include page="...">
<jsp:param name="..." value="..." />
</jsp:include>

● 表达式语言(EL)的隐式对象以及该对象的作用
答:
EL表达式中定义了11个隐式对象包括:

pageContext、

initParam(访问上下文参数)、

param(访问请求参数)、

paramValues、

header(访问请求头)、

headerValues、

cookie(访问cookie)、

applicationScope(访问application作用域)、

sessionScope(访问session作用域)、

requestScope(访问request作用域)、

pageScope(访问page作用域)。

● JSP有哪些内置对象以及作用?
答:
JSP有9个内置对象:
- request:对应HttpServletRequest封装客户端请求服务端信息,其中包含来自GET或POST请求的参数;
- response:对应HttpServletRespons封装服务端相应客户端信息;

- session:对应HttpSession用于客户端与服务器端的会话;
- pageContext:通过该对象可以获取其他对象;
- application:封装服务器运行环境的对象;
- out:输出服务器响应的输出流对象;
- config:Web应用的配置对象;
- page:JSP页面本身(相当于Java程序中的this);
- exception:封装页面抛出异常的对象。



● jsp有哪些动作? 这些动作的作用又分别是什么?
答:
JSP 共有以下6种基本动作 

jsp:include:在页面被请求的时候引入一个文件。 

jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。 

jsp:getProperty:输出某个JavaBean的属性。 

jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。



Request对象的主要方法是什么?

答:

setAttribute(String name,Object):设置名字为name的request的参数值
getAttribute(String name):返回由name指定的属性值

removeAttribute(String name):删除请求中的一个属性
getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding():返回请求中的字符编码方式
getHeader(String name):获得HTTP协议定义的文件头信息
getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例
getInputStream():返回请求的输入流,用于获得请求中的数据
getMethod():获得客户端向服务器端传送数据的方法
getParameter(String name):获得客户端传送给服务器端的有name指定的参数值
getParameterNames():获得客户端传送给服务器端的所有参数的名字
getParameterValues(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getSession([Boolean create]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号

  • getAttribute与getParame的区别

getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得
getParameter表示接收参数,参数为页面提交的参数,包括:表单提交的参数、URL(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter),


● 四种会话跟踪技术分别是什么?
答:
URL重写、隐藏表单域、Cookie、Session。

 JSP和Servlet有哪些相同点和不同点?
答:
JSP 是Servlet技术的扩展。

Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。

JSP侧重于视图,Servlet主要用于控制逻辑


● web.xml文件中可以配置哪些内容?
答:

监听器(listener)、过滤器(filter)、 Servlet、相关参数、会话超时时间、安全验证方式、错误页面等,下面是一些开发中常见的配置:

①配置Spring上下文加载监听器加载Spring配置文件并创建IoC容器:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

②配置Spring的OpenSessionInView过滤器来解决延迟加载和Hibernate会话关闭的矛盾:

<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

③配置会话超时时间为10分钟:

<session-config>
<session-timeout>10</session-timeout>
</session-config>

④配置404和Exception的错误页面:
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>

<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
⑤配置安全认证方式:

<security-constraint>
<web-resource-collection>
<web-resource-name>ProtectedArea</web-resource-name>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>BASIC</auth-method>
</login-config>

<security-role>
<role-name>admin</role-name>
</security-role>

● Javaweb中的监听器的理解?
答:
当被监听对象发生状态变化时,监听器会根据代码逻辑执行动作

 

● 过滤器有哪些作用?以及过滤器的用法?
答:
Java Web开发中的过滤器(filter)是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联,如果有,那么容器将把请求交给过滤器进行处理。
常见的过滤器用途包括:对用户的访问请求进行记录和审核(如:过滤一些敏感的字符串)、对用户发送的数据进行过滤或替换(如:避免中文乱码【规定Web资源都使用UTF-8编码】)、加解密处理。

 


●Servlet如何获取用户配置的初始化参数以及服务器上下文参数?
答:

在Servlet中直接调用getInitParameterr(java.lang.Stringname)方法来读取初始化参数。

ServletConfig接口的getInitParameter(java.lang.Stringname)方法。


● 请问使用Servlet如何获取用户提交的查询参数以及表单数据?
答:
HttpServletRequest的getParameter()方法通过参数名获得参数值。

HttpServletRequest的getParameterValues()方法,获得包含多个值的参数(例如复选框)。

HttpServletRequest的getParameterMap()获得一个参数名和参数值的映射。


 

● Java的Web项目中实现文件上传和下载?
答:


Servlet接口中有哪些方法,Servlet的生命周期
答:

Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关:
- init(ServletConfig config) throws ServletException
- service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
- void destory()
- getServletInfo()
- getServletConfig()

Servlet的生命周期:
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,

容器运行其init()方法进行Servlet的初始化;

请求到达时调用Servlet的service()方法,service()方法会根据需要调用请求对应的doGet或doPost等方法;

当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法。


● Servlet和CGI的区别?
答:
SServlet通过多线程方式运行service()方法,一个实例可以服务于多个请求,

CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet。


● forward与redirect区别
答:
1.从地址栏显示来说

forward:地址栏还是原来的地址.

redirect浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

2.从数据共享来说

forward:转发页面和转发到的页面可以共享request里面的数据.

redirect:不能共享数据.

3.从效率来说

forward:高.

redirect:低.

 

 

 

 

● MVC

答:

MVC 是Model-View-Controller的简写,模型-视图-控制器。

”Model” 数据层,程序需要操作的数据或信息。,

 “View” 视图层,提供给用户的操作界面。(由JSP页面产生)

”Controller” 控制层,它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作。

 

使用标签库有什么好处?常用JSP标签?

答:

使用标签库的好处包括以下几个方面:

- 分离JSP页面的内容和逻辑,简化了Web开发;

- 可以创建自定义标签来封装业务逻辑和显示逻辑;

<c:if>、<c:choose>、<c: when>、<c: otherwise>、<c:forEach>等

 

get和post请求

答:

 

GET

POST

后退按钮/刷新

无害

数据会被重新提交。

书签

可收藏为书签

不可收藏为书签

历史

参数保留在浏览器历史中。

参数不会保存在浏览器历史中。

对数据长度的限制

限制(URL 的最大长度是 2048 个字符)。

无限制。

对数据类型的限制

只允许 ASCII 字符。

没有限制。

安全性

GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息绝不要使用 GET !

POST 安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

可见性

数据在 URL 可见。

数据不会显示在 URL 中。

 

● 请你解释一下,什么是Web Service?

答:

从表面上看,Web Service就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法透明的调用这个应用程序,不需要了解它的任何细节,跟你使用的编程语言也没有关系。例如可以创建一个提供天气预报的Web Service,那么无论你用哪种编程语言开发的应用都可以通过调用它的API并传入城市信息来获得该城市的天气预报。之所以称之为Web Service,是因为它基于HTTP协议传输数据,这使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件,就可相互交换数据或集成。

 

SOA(Service-Oriented Architecture,面向服务的架构),SOA是一种思想,它将应用程序的不同功能单元通过中立的契约联系起来,独立于硬件平台、操作系统和编程语言,使得各种形式的功能单元能够更好的集成。显然,Web Service是SOA的一种较好的解决方案,它更多的是一种标准,而不是一种具体的技术。

 

 如何设置请求的编码以及响应内容的类型?

答:

通过请求对象ServletRequest的setCharacterEncoding(String)方法可以设置请求的编码,

通过响应对象ServletResponse的setContentType(String)方法可以设置响应内容的类型,也可以通过HttpServletResponsed对象的setHeader(String, String)方法来设置。

要彻底解决乱码问题,应该让页面、服务器、请求和响应、Java程序都使用统一的编码,最好选择是UTF-8;

 

● 说明 BS与CS 的联系,还有区别。

答:

C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle、Sybase、Informix或 SQL Server。客户端需要安装专用的客户端软件。

B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),如Netscape Navigator或Internet Explorer,服务器安装Oracle、Sybase、Informix或 SQL Server等数据库。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现。浏览器通过Web Server 同数据库进行数据交互。

C/S 与 B/S 区别:

C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务.

B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行

 

 

cookie 和 session 的区别?

答:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。

4、单个cookie保存的数据不能超过4K。

 

 

 

 

 

 

Spring

IOC和AOP是什么?

答:

spring的核心是反转控制(IOC)和面向切面(AOP)

AOP面向切面编程:简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。实现aop的方法:采用动态代理技术,采用静态织入方式,Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理要求被代理的类必须实现InvocationHandler接口。如果没有实现接口,那么Spring 使用CGLIB来动态代理目标类。CGLIB是通过继承的方式做的动态代理,因此如果类被标记为final,是无法使用CGLIB做动态代理的。

 

AO应用场景:Authentication 权限 ,Caching 缓存 ,Context passing 内容传递 ,Error handling 错误处理 ,Lazy loading 懒加载 ,Debugging 调试 ,Performance optimization 性能优化 ,Persistence 持久化 ,Resource pooling 资源池 ,Synchronization 同步,Transactions 事务。

 

aop的相关概念:

切面aspect

连接点join point

通知advice

切点 pointcut

引入introduction

目标对象target object

aop代理 aop proxy

织入weavin

 

IOC控制反转:由原先在类内部控制(new出依赖的类)变成了由第三方容器控制(通过set方法注入或注解原理),主动依赖变成了被动依赖,叫做控制反转,也叫依赖注入。它的原理是用反射技术对javabean的set方法进行操作,通过ApplicationContext这个第三方容器(可以当作特别大的工厂,管理着各种被依赖的类)向javabean中注入。

 

使用ioc的好处:

资源集中管理

减低资源的依赖程度

便于测试

减少对象的穿件和内存的消耗

 

 

你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?

答:

a. 连接点(Joinpoint):程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。

b. 切点(Pointcut):如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。

c. 增强(Advice):增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。

d. 引介(Introduction):引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过引介功能,可以动态的未该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

e. 织入(Weaving):织入是将增强添加到目标类具体连接点上的过程,AOP有三种织入方式:①编译期织入:需要特殊的Java编译期(例如AspectJ的ajc);②装载期织入:要求使用特殊的类加载器,在装载类的时候对类进行增强;③运行时织入:在运行时为目标类生成代理实现增强。Spring采用了动态代理的方式实现了运行时织入,而AspectJ采用了编译期织入和装载期织入的方式。

f. 切面(Aspect):切面是由切点和增强(引介)组成的,它包括了对横切关注功能的定义,也包括了对连接点的定义。

 

 

 

● 请简单谈一下spring框架的优点都有哪些?

答:

1.Spring是个容器,可以将多个对象的创建和依赖关系的维护都交给Spring管理

2.AOP面向切面编程的支持,方便进行权限拦截和监控等功能

3.方便事务的管理

4.Spring与Junit整合,方便程序的测试

5.方便整合各个优秀的框架.如struts2.mybatis等

6.降低一些java API的使用难度.如javaMail ,JDBC等

 

● 介绍一下spring?

答:

Spring是一个轻量级框架,可以一站式构建你的企业级应用。

Spring的模块

1、Core Container(Spring的核心)【重要】

2、AOP(面向切面变成)【重要】

3、Messaging(消息发送的支持)

4、Data Access/Integration(数据访问和集成)

5.Web(主要是SpringWeb内容,包括MVC)【重要】

6.Test(Spring测试支持,包含JUint等测试单元的支持)

7.Instrumentation(设备支持,比如Tomcat的支持)

 

● 持久层框架都有哪些?

- Hibernate

- MyBatis

 

 

 


● Spring中自动装配的方式
答:

 - no:不进行自动装配,通过“ref”attribute手动设定。

<bean id="cat_c" class="com.spring.auto.autowire.Cat"></bean>
    <bean id="dog_d" class="com.spring.auto.autowire.Dog"></bean>
    <bean id="test" class="com.spring.auto.autowire.Person">
        <property name="cat" ref="cat_c"/>
        <property name="dog" ref="dog_d"/>
        <property name="say" value="测试"/>
    </bean>

- byName:根据Bean的名字进行自动装配。

<bean id="cat" class="com.spring.auto.autowire.Cat"></bean>
    <bean id="dog" class="com.spring.auto.autowire.Dog"></bean>
    <bean id="test" class="com.spring.auto.autowire.Person" autowire="byName">
        <property name="say" value="测试"/>
    </bean>


- byType:根据Bean的类型进行自动装配。使用byType首先需要保证同一类型的对象,在spring容器中唯一,若不唯一会报不唯一的异常。

<bean id="cat" class="com.spring.auto.autowire.Cat"></bean>
    <bean id="dog" class="com.spring.auto.autowire.Dog"></bean>
    <bean id="test" class="com.spring.auto.autowire.Person" autowire="byType">
        <property name="say" value="测试"/>
    </bean>

若配置文件中有两个类型相同的bean,将抛出UnsatisfiedDependencyException异常

  <bean id="cat" class="com.spring.auto.autowire.Cat"></bean>
    <bean id="cat_c" class="com.spring.auto.autowire.Cat"></bean>


- constructor:使用构造方法完成对象注入,根据构造方法的参数类型进行对象查找。

<bean id="cat" class="com.spring.auto.autowire.Cat"></bean>
    <bean id="dog" class="com.spring.auto.autowire.Dog"></bean>
    <bean id="test" class="com.spring.auto.autowire.Person" autowire="constructor">
        <constructor-arg index="2" value="55"></constructor-arg>
    </bean>


- autodetect:如果有默认的构造器,则通过constructor的方式进行自动装配,否则使用byType的方式进行自动装配。

Spring中Bean的作用域?






● Spring中BeanFactory和ApplicationContext的区别是什么?
答:
BeanFactory: 
BeanFactory是spring中比较原始,比较古老的Factory。因为比较古老,所以BeanFactory无法支持spring插件,例如:AOP、Web应用等功能。

ApplicationContext 
ApplicationContext是BeanFactory的子类,因为古老的BeanFactory无法满足不断更新的spring的需求,于是ApplicationContext就基本上代替了BeanFactory的工作,以一种更面向框架的工作方式以及对上下文进行分层和实现继承,并在这个基础上对功能进行扩展: 
<1>MessageSource, 提供国际化的消息访问 
<2>资源访问(如URL和文件) 
<3>事件传递 
<4>Bean的自动装配 
<5>各种不同应用层的Context实现

区别:

<1>如果使用ApplicationContext,如果配置的bean是singleton,那么不管你有没有或想不想用它,它都会被实例化。好处是可以预先加载,坏处是浪费内存。 
<2>BeanFactory,当使用BeanFactory实例化对象时,配置的bean不会马上被实例化,而是等到你使用该bean的时候(getBean)才会被实例化。好处是节约内存,坏处是速度比较慢。多用于移动设备的开发。 
<3>没有特殊要求的情况下,应该使用ApplicationContext完成。因为BeanFactory能完成的事情,ApplicationContext都能完成,并且提供了更多接近现在开发的功能。

● 依赖注入的方式有哪几种?答:
答:

Set注入 2、构造器注入 3、接口注入

 @Controller和@RestController的区别是什么?
答:
@RestController注解相当于@ResponseBody + @Controller合在一起的作用

● autowired 和resource区别是什么?
答:
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
(1)@Autowired
@Autowired为Spring提供的注解,按照byType注入。默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
(2)@Resource
@Resource默认按照ByName自动注入


● bean的生命周期
答:
Spring生命周期流程图:

 

 

 

 Spring MVC的工作原理,流程

答:

 

①客户端的所有请求都交给前端控制器DispatcherServlet来处理,它会负责调用系统的其他模块来真正处理用户的请求。

② DispatcherServlet收到请求后,将根据请求的信息(包括URL、HTTP协议方法、请求头、请求参数、Cookie等)以及HandlerMapping的配置找到处理该请求的Handler(任何一个对象都可以作为请求的Handler)。

③在这个地方Spring会通过HandlerAdapter对该处理器进行封装。

④ HandlerAdapter是一个适配器,它用统一的接口对各种Handler中的方法进行调用。

⑤ Handler完成对用户请求的处理后,会返回一个ModelAndView对象给DispatcherServlet,ModelAndView顾名思义,包含了数据模型以及相应的视图的信息。

⑥ ModelAndView的视图是逻辑视图,DispatcherServlet还要借助ViewResolver完成从逻辑视图到真实视图对象的解析工作。

⑦ 当得到真正的视图对象后,DispatcherServlet会利用视图对象对模型数据进行渲染。

⑧ 客户端得到响应,可能是一个普通的HTML页面,也可以是XML或JSON字符串,还可以是一张图片或者一个PDF文件。

 

 

● springmvc和spring-boot区别是什么?

答:

Spring 的 IOC 和 AOP,IOC提供了依赖注入的容器,而AOP解决了面向切面的编程,因为 Spring 的配置非常复杂,各种xml,properties处理起来比较繁琐。于是为了简化开发者的使用,Spring社区创造性地推出了Spring Boot,极大降低了Spring使用门槛,但又不失Spring原本灵活强大的功能。

 

● Spring MVC注解的优点?

答:

1、XML配置起来有时候冗长,此时注解可能是更好的选择,如jpa的实体映射;注解在处理一些不变的元数据时有时候比XML方便的多,比如springmvc的数据绑定,如果用xml写的代码会多的多;

 

2、注解最大的好处就是简化了XML配置;其实大部分注解一定确定后很少会改变,所以在一些中小项目中使用注解反而提供了开发效率,所以没必要一头走到黑;

 

3、注解相对于XML的另一个好处是类型安全的,XML只能在运行期才能发现问题。

 

 

 

Mybatis

● MyBatis中的动态SQL是什么意思?

答:

- if

- choose / when / otherwise

- trim

- where

- set

- foreach

 

MyBatis中命名空间namespace的作用是什么?

答:

MyBatis中,为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个SQL语句就成了定义在这个命名空间中的一个ID。只要我们能够保证每个命名空间中这个ID是唯一的,即使在不同映射文件中的语句ID相同,也不会再产生冲突了。

 

 

 

Mybatis和Hibernate的区别?

答:

Hibernate:Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL的自动生成和执行

Mybatis:Mybatis 是一种“Sql Mapping”的ORM实现。通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定 POJO 。

 

 

 

 

 

Redis

 

● redis的List能在什么场景下使用?

答:

Redis 中list的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过lpush将消息放入 list,消费者便可以通过rpop取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择sorted set。而pub/sub功能也可以用作发布者 / 订阅者模型的消息。

 

● 介绍一下aof和rdb都有哪些优点?以及两者有何区别?

答:

RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

 

AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。你甚至可以关闭持久化功能,让数据只在服务器运行时存在。

 

RDB 的优点:

 

RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

 

RDB 的缺点:

 

如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。

 

AOF 的优点:

 

使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。

 

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

 

AOF 的缺点:

 

对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。

 

● 缓存的优点是什么?

答:

优点:1、减少了对数据库的读操作,数据库的压力降低 2、加快了响应速度

 

● redis为什么是单线程?

答:

因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。缺点:服务器其他核闲置。

 

●为什么 redis 读写速率快、性能好?

答:

Redis是纯内存数据库,相对于读写磁盘,读写内存的速度就不是几倍几十倍了,一般,hash查找可以达到每秒百万次的数量级。

 

多路复用IO,“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)。可以直接理解为:单线程的原子操作,避免上下文切换的时间和性能消耗;加上对内存中数据的处理速度,很自然的提高redis的吞吐量。

 

● redis的主从复制怎么做的?

答:

第一阶段:与master建立连接

第二阶段:向master发起同步请求(SYNC)

第三阶段:接受master发来的RDB数据

第四阶段:载入RDB文件

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值