Java笔试必考知识点合集四

1.Java枚举的内部实现:

枚举类在后台实现时,实际上是转化为一个继承了java.lang.Enum类的实体类,原先的枚举类型变成对应的实体类型,上例中AccountType变成了个class AccountType,并且会生成一个新的构造函数,若原来有构造函数,则在此基础上添加两个参数,生成新的构造函数,如上例子中:

实例枚举源码:

enum AccountType
{
    SAVING, FIXED, CURRENT;
    private AccountType()
    {
        System.out.println(“It is a account type”);
    }
}
class EnumOne
{
    public static void main(String[]args)
    {
        System.out.println(AccountType.FIXED);
    }
}
1
private AccountType(){ System.out.println(“It is a account type”); }
会变成:
1
2
private AccountType(String s,  int i){
     super (s,i); System.out.println(“It is a account type”); }
而在这个类中,会添加若干字段来代表具体的枚举类型:
1
2
3
public static final AccountType SAVING;
public static final AccountType FIXED;
public static final AccountType CURRENT;
而且还会添加一段static代码段:
1
2
3
4
5
6
static {
     SAVING =  new AccountType( "SAVING" 0 );
     ...  CURRENT =  new AccountType( "CURRENT" 0 );
    $VALUES =  new AccountType[]{
          SAVING, FIXED, CURRENT
     } }
以此来初始化枚举中的每个具体类型,也因此会执行多次构造函数。(并将所有具体类型放到一个$VALUE数组中,以便用序号访问具体类型)

2.HttpServlet容器响应Web客户请求流程

  • 1)Web客户向Servlet容器发出Http请求;
  • 2)Servlet容器解析Web客户的Http请求;
  • 3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
  • 4)Servlet容器创建一个HttpResponse对象;
  • 5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把  HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
  • 6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
  • 7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
  • 8)Servlet容器把HttpServlet的响应结果传给Web客户。
doGet() 或 doPost() 是创建HttpServlet时需要覆盖的方法.

3.中间件

     中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。
(简单来说,中间件并不能提高内核的效率,一般只是负责网络信息的分发处理)
中间件特点的描述:
1. 中间件应支持标准的协议和接口
2. 中间件可运行于多种硬件和操作系统平台上
3. 跨越网络,硬件,操作系统平台的应用或服务可通过中间件透明交互

4.Integer需要注意的点

代码片段
1
2
3
4
5
6
7
8
9
10
11
12
public class Test03 {
     
     public static void main(String[] args) {
        
         Integer f1 =  100 , f2 =  100 , f3 =  150 , f4 =  150 ;
          
         System. out.println( f1 == f2);  //true
         System. out.println( f3 == f4);  //false
     }
}

当我们给一个Integer赋予一个int类型的时候会调用Integer的静态方法valueOf。 
Integer f1 = Integer.valueOf(100); 
Integer f2 = Integer.valueOf(100); 
Integer f3 = Integer.valueOf(150); 
Integer f4 = Integer.valueOf(150); 
思考:那么Integer.valueOf()返回的Integer是不是是重新new Integer(num);来创建的呢?如果是这样的话,那么== 比较返回都是false,因为他们引用的堆地址不一样。

具体来看看Integer.valueOf的源码
1
2
3
4
5
6
public static Integer valueOf( int i) {
         
         if (i >= IntegerCache.low && i <= IntegerCache.high)
             return IntegerCache.cache[i + (-IntegerCache.low)];
         return new Integer(i);
}
在IntegerCache中cache数组初始化如下,存入了-128 - 127的值
1
2
3
4
5
cache =  new Integer[(high - low) +  1 ];
int j = low;
for int k =  0 ; k < cache.length ; k ++)
     cache[k] =
     cache[k] =  new Integer(j ++);
从上面我们可以知道给Interger 赋予的int数值在-128 - 127的时候,直接从cache中获取,这些cache引用对Integer对象地址是不变的,但是不在这个范围内的数字,则new Integer(i) 这个地址是新的地址,不可能一样的.

5.Java多线程需要注意的点

Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。 
共同点  
  • 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。 
  • 2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。 
  • 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。 
  • 需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。 
不同点  :  
  • 1.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。 
  • sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。 
  • 2.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 
  • 3.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常 
  • 4.sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
  • 5.wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

6.abstract、static、final

关键字abstract:

  • 抽象方法只能定义在抽象类中;
  • 抽象方法和抽象类必须由abstract修饰;
  • abstract关键字只能描述类和方法,不能描述变量;
  • 抽象方法只定义方法声明,不定义方法实现;
  • 抽象类不可以被实例化(创建对象),只有通过子类继承抽象类并覆盖抽象类中的所有抽象方法后,该子类才可以被实例化,否则该子类还是一个抽象类。
  • 抽象类中有构造函数用于给子类对象进行初始化,同时抽象类中可以含有非抽象方法;
  • abstract关键字不可以与final,private,static关键字共存,因为被final修饰的方法不可以被重写,意味着子类不可以重写该方法,如果abstract和final共同修饰父类中的方法,子类要实现抽象方法(abstract的作用),而final又不让该方法重写,这相互矛盾。如果private和abstract共同修饰父类中的方法,private修饰则该方法不可以被子类访问,但是abstract修饰需要子类去实现,两者产生矛盾。如果static和abstract共同修饰父类中的方法,static表示是静态的方法,随着类的加载而加载,则该方法不需要在子类中去实现,这与abstract关键字矛盾。 
static关键字:
  • static用于修饰成员变量和成员函数,想要实现对象中的共性数据的对象共享,可以将这个数据进行静态修饰,被静态修饰的成员可以直接被类名调用,静态随着类的加载而加载,而且优先于对象存在。
  • 静态方法只能访问静态成员(静态方法和静态变量),不可以访问非静态成员,这是因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
  • 静态方法中不能使用this和super关键字,因为this代表本类对象,super代表父类对象,而静态时,有可能没有对象存在,所以this和super无法使用。 
final关键字:
  • final关键字可以修饰类,方法,变量(成员变量内,局部变量,静态变量)。
  • 被final修饰的类是一个最终类,不可以被继承,被final修饰的方法是一个最终方法,不可以被覆盖,但是可以被继承。
  • 被final修饰的变量只能是一个常量,只能赋值一次。
  • 内部类被定义在类中的局部位置上时,只能访问局部被final修饰的局部变量。

补充:

  • 成员变量有初始值,局部变量没有初始值。
  • 创建String时,会在字符串常量池中寻找,当找到需要的hello时,不进行字符串的创建,引用已有的。 所以,String s = "hello";String t = "hello";s==t返回true,s.equals(t)也是true。
  • getParameter()是获取POST/GET传递的参数值;
  • getInitParameter获取Tomcat的server.xml中设置Context的初始化参数
  • getAttribute()是获取对象容器中的数据值;
  • getRequestDispatcher是请求转发
  • java,exe是java虚拟机
  • javadoc.exe用来制作java文档
  • jdb.exe是java的调试器
  • javaprof,exe是剖析工具
  • java8中允许接口有默认方法和类方法



猜你喜欢

转载自blog.csdn.net/goodli199309/article/details/80946532