Java面试知识点一

个人的总结如下,最近准备开始找java开发的工作,做的面试题 比较多,现总结一下,希望支持一下!不明白的可以留言,大家一起学习进步!

1、对于abstract声明的类,可以被抽象类继承也可以被非抽象类继承,不可以实例化。
2、从ServeletConfig中可以获得Servlet的初始化参数。
ServletContext对象:servlet容器在启动时会加载web应用,并为每个web应用创建唯一的servlet context对象,可以把ServletContext看成是一个Web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据。ServletContext对象是真正的一个全局对象,凡是web容器中的Servlet都可以访问。整个web应用只有唯一的一个ServletContext对象。
servletConfig对象:用于封装servlet的配置信息。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对servlet自身有效,一个servlet的ServletConfig对象不能被另一个servlet访问。
3、super关键字是在子类对象内部指代其父类对象的引用。super出现在继承了父类的子类中。有三种存在方式:
第一种:super.xxx;(xxx为变量名或对象名)
这种方法意义为,获取父类中的名字为xxx的变量或方法引用。
使用这种方法可以直接访问父类中的变量或对象,进行修改赋值等操作
第二种:super.xxx();(xxx为方法名)
这种方法意义为,直接访问并调用父类中的方法。
第三种:super();
这种方法意义为,调用父类的初始化方法,其实就是调用父类中的public xxx()方法
此外,super只能指代其直接父类,在父类中调用super能指代父类的父类
4、输出结果为:构造块 构造块 静态块 构造块

public class B
{
    public static B t1 = new B();
    public static B t2 = new B();
    {
        System.out.println("构造块");
    }
    static
    {
        System.out.println("静态块");
    }
    public static void main(String[] args)
    {
        B t = new B();
    }
}


解释:静态变量和静态代码块的执行顺序就是代码前后的顺序,所以 依次会执行t1,t2和静态代码块; t1执行时,会调用无参构造器,无参构造器会先执行super()调用父类的无参构造器(这里不存在这一步),然后执行普通代码块,然后执行无参构造器本身的内容(这里也不存在),所以类加载后执行两次普通代码块,一次静态代码块,在new对象时又调用无参构造器,执行普通代码块的内容。静态代码块只执行一次。
5、
count = 0
count = count ++;
输出count = 0;
jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。jvm会这样运行这条语句:
步骤1 JVM把count值(其值是0)拷贝到临时变量区。 
步骤2 count值加1,这时候count的值是1。 步骤3 返回临时变量区的值,注意这个值是0,没修改过。 步骤4 返回值赋值给count,此时count值被重置成0。
6、abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。  
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。  
    下面比较一下两者的语法区别:  
    1.抽象类可以有构造方法,接口中不能有构造方法。  
    2.抽象类中可以有普通成员变量,接口中没有普通成员变量  
    3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。  
    4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然  
    eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。  
    5. 抽象类中可以包含静态方法,接口中不能包含静态方法  
    6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。  
    7. 一个类可以实现多个接口,但只能继承一个抽象类。  
下面接着再说说两者在应用上的区别:  
    接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用。
7、  形式参数就是函数定义时设定的参数。例如函数头 int min(int x,int y,int z) 中 x,y,z 就是形参。实际参数是调用函数时所使用的实际的参数。对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。 不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。
8、

public static void main(String args[]) {
   Thread t = new Thread() {
            public void run() {
                pong();
            }
        };
        t.run();
        System.out.print("ping");
    }
    static void pong() {
        System.out.print("pong");
    }


输出结果:pongping
解析:这里需要注意Thread的start和run方法用start方法才能真正启动线程,此时线程会处于就绪状态,一旦得到时间片,则会调用线程的run方法进入运行状态。而run方法只是普通方法,如果直接调用run方法,程序只会按照顺序执行主线程这一个线程。
若调用start,则先执行主线程的,后执行子线程的,即结果为pingpong
若调用run,相当于函数调用,顺序执行,即结果为pongping
9、linkedlist类是实现了List接口,而不是继承。AbstractSet类实现Set接口。HashSet继承 AbstractSet类,同时也实现set。
10、java语言是强类型语言,支持的类型分为两类:基本类型和引用类型。基本类型包括boolean类型和数值类型,数值类型有整数类型和浮点类型。整数类型包括:byte、short、int、long和char;浮点类型包括:float和double。引用类型包括类、接口和数组类型以及特殊的null类型。
11、普通的java对象是通过new关键字把对应类的字节码文件加载到内存,然后创建该对象的。反射是通过一个名为Class的特殊类,Class.forName("className");得到类的字节码对象,然后用newInstance()方法在虚拟机内部构造这个对象(针对无参构造函数).也就是说反射机制让我们可以先拿到java类对应的字节码对象,然后动态的进行任何可能的操作,包括
    (1)在运行时判断任意一个对象所属的类
    (2)在运行时构造任意一个类的对象
    (3)在运行时判断任意一个类所具有的成员变量和方法
    (4)在运行时调用任意一个对象的方法
这些都是反射的功能。使用反射的主要作用是方便程序的扩展。
12、ResultSet结果集读取数据的方法主要是getXXX() ,他的参数可以使整型表示第几列(是从1开始的),还可以是列名。
13、多个线程可同时操作一个数据,为了保证该数据的准确性,可将操作该数据的部分改为(同步)。
14、在Web应用程序的文件与目录结构中,web.xml是放置在(WEB-INF目录)中。
15、面向对象的五个基本原则: 
(1)单一职责原则(Single-ResposibilityPrinciple):一个类,最好只做一件事,只有一个引起它的变化。单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。 
(2)开放封闭原则(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。 
(3)Liskov替换原则(Liskov-SubstituionPrinciple):子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。 
(4)依赖倒置原则(Dependecy-InversionPrinciple):依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。 
(5)接口隔离原则(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口。
16、(1). byte a1 = 2, a2 = 4, a3;
    (2). short s = 16;
    (3). a2 = s;  (编译出错)
    (4). a3 = a1 * a2 (编译出错)
byte+byte=int,低级向高级是隐式类型转换,高级向低级必须强制类型转换,byte<char(2)=short(2)<int<long<float<double
17、HttpSession session = request.getSession() 等同于 request.getSession(true),如果不存在就创建一个新的session。HttpSession session = request.getSession(false);  不创建session
18、Java初始化顺序:
(1)继承体系的所有静态成员初始化(先父类,后子类)
(2)父类初始化完成(普通成员的初始化-->构造函数的调用)
(3)子类初始化(普通成员-->构造函数)
19、Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。sleep()和wait()共同点 : 
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)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
20、A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:
        A a0 = new A();
A a1 = new B();
A a2 = new C();都是正确的,继承具有多态性,可以是本类的引用指向本类对象,也可以是本类的引用指向子类对象。
21、符号?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E及其父类
22、preparedStatement和statement的区别与联系:在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也    就是说,在任何时候都不要使用Statement。PreparedStatement 接口继承 Statement ,   PreparedStatement 实例包含已编译的 SQL 语句,  所以其执行速度要快于 Statement 对象。 Statement为一条Sql语句生成执行计划, 如果要执行两条sql语句 
select colume from table where colume=1;select colume from table where colume=2; 会生成两个执行计划 一千个查询就生成一千个执行计划! PreparedStatement用于使用绑定变量重用执行计划 select colume from table where colume=:x; 通过set不同数据只需要生成一次执行计划,可以重用。
创建Statement是不传参的,PreparedStatement是需要传入sql语句。即:
Statement sta=con.createStatement();
ResultSet rst=sta.executeQuery(“select * from book”);


PreparedStatement pst=con.prepareStatement(“select * from book”);
ResultSet rst=pst.executeQuery();


23、事务的隔离级别是由数据库系统实现的。在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别;为了解决更新丢失,脏读,不可重读(包括虚读和幻读)等问题在标准SQL规范中,定义了4个事务隔离级别,分别为未授权读取,也称为读未提交(read uncommitted);授权读取,也称为读提交(read committed);可重复读取(repeatable read);序列化(serializable)。
24、要写一个线程类,可以继承Thread方法,然后override他的run()方法,另一种方法是实现Runable接口,即为实现run()方法。start()是启动一个线程的方法。
25、假设有以下代码String s = "hello":String t = “hello”;char c [ ] = {'h','e','1','1','o'};
   s.equals(t)  ->true 
   t.equals(c) ->false   Sting 类保存字符串只是保存所有单单的字符串;  而 char[] 字符数组 会在最后自动加上'\n';
   s==t;  ->true
26、出于运行速率的考虑,java编译器会把经常经常访问的变量放到缓存(严格讲应该是工作内存)中,读取变量则从缓存中读。但是在多线程编程中,内存中的值和缓存中的值可能会出现不一致。volatile用于限定变量只能从内存中读取,保证对所有线程而言,值都是一致的。但是volatile不能保证原子性,也就不能保证线程安全。
27、Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。 
Ant特点 ›
没有一个约定的目录结构 ›必须明确让ant做什么,什么时候做,然后编译,打包 ›没有生命周期,必须定义目标及其实现的任务序列 ›没有集成依赖管理 
Maven特点 
拥有约定,知道你的代码在哪里,放到哪里去 ›拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程 › 只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情 ›拥有依赖管理,仓库管理
28、Spring MVC的核心控制器DispatcherServlet的作用:(1)负责接收http请求(2)加载配置文件(3)初始化上下应用对象applicationContext
29、final修饰的成员变量为基本数据类型是,在赋值之后无法改变。当final修饰的成员变量为引用数据类型时,在赋值后其指向地址无法改变,但是对象内容还是可以改变的。final修饰的成员变量在赋值时可以有三种方式。1、在声明时直接赋值。2、在构造器中赋值。3、在初始代码块中进行赋值。
30、doGet/doPost 则是在 javax.servlet.http.HttpServlet 中实现的。
31、-Xmx:最大堆大小
-Xms:初始堆大小(即最小内存值)
-Xmn:年轻代大小
-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值
要理解eden和survivor区,先要知道垃圾收集算法中的 复制算法。
复制算法:将区域分成两部分,其中一部分作为保留空间,另一部分作为使用空间、当发生垃圾回收时,首先检查使用空间里有哪些对象是存活的,检查完之后把存活的对象复制到保留空间(这样复制过来的好处是减少了内存碎片,如果直接在使用空间清除的话,那空间会很零散)里,然后清洗使用空间。这个eden就相当于是使用空间,survivor就相当于是保留空间,通常情况下eden会比survivor大的多,因为eden和survivor都是属于新生代(还有老生代,jvm 将堆分为新生代和老生代),新生代里的对象一般都是朝生夕死,所以活下来的不多,所以保留空间小一些就好了。
GC就是垃圾回收了,是java语言的一大特点,我们生成的对象空间不需要自己手动去释放,jvm自有GC线程来帮我们清理不用的对象。
32、JUnit是一个Java语言的单元测试框架。
33、HashTable与HashMap的比较。
34、1.Serial New/Serial Old
Serial/Serial Old收集器是最基本最古老的收集器,它是一个单线程收集器,并且在它进行垃圾收集时,必须暂停所有用户线程。Serial New收集器是针对新生代的收集器,采用的是Copying算法,SerialOld收集器是针对老年代的收集器,采用的是Mark-Compact算法。它的优点是实现简单高效,但是缺点是会给用户带来停顿。
2.Parallel New
Parallel New收集器是Serial收集器的多线程版本(参照Serial New),使用多个线程进行垃圾收集。
3.Parallel Scavenge
Parallel Scavenge收集器是一个新生代的多线程收集器(并行收集器),它在回收期间不需要暂停其他用户线程,其采用的是Copying算法,该收集器与前两个收集器有所不同,它主要是为了达到一个可控的吞吐量。
4.Parallel Old
Parallel Old是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact算法。
5.CMS
    CMS(Current Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-Sweep算法。
6.G1
    G1收集器是当今收集器技术发展最前沿的成果,它是一款面向服务端应用的收集器,它能充分利用多CPU、多核环境。因此它是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。
35、interface中合法定义:
     public void main(String[] args);
boolean setFlag(Boolean[] test);
public float get(int x);
非法定义:
private int getSum(); // 接口中不能定义私有方法
36、object对象中含有以下方法:
       clone(),equals(),finalize(),getClass(),notify(),notifyAll(),hashCode(),toString(),wait()
37、HashTable是线程安全的一个Collection. Vector是线程安全的ArrayList TreeSet和LinkedList都不是线程安全的.
38、JDK提供的用于并发编程的同步器:
Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire()获取一个许可,如果没有就等待,而 release() 释放一个许可。
CyclicBarrier主要的方法就是一个:await()。await()方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。

直译过来就是倒计数(CountDownLatch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。
39、选项中哪一行代码可以添加 题目中而不产生编译错误?
public abstract class MyClass {
public int constInt = 5;
//add code here
public void method() {
  }
}


A:public abstract void method(int a); //不产生编译错误!抽象类可以包含抽象方法,也可以不包含,虽然A方法名是method,与题目中的方法同名,但是参数不同,是重载方法。
B:constInt = constInt + 5;
//产生!在类中不能constInt = constInt + 5;  方法中可以
C:public int method();//方法名与题目中的方法名相同,返回值不能作为重载的依据
D:public abstract void anotherMethod(){} //抽象方法不能有方法体
40、一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性。
41、Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为:".*?(?=\\()"
42、代码:
Boolean flag = false;
if (flag = true)
{
System.out.println(“true”);
}
else
{
System.out.println(“false”);
}


会正常输出:true
43、代码输出:finally finished
public class Test
{
public static int aMethod(int i)throws Exception
{
try{
return i / 10;
}
catch (Exception ex)
{
throw new Exception("exception in a Method");
} finally{
System.out.printf("finally");
}
}
 
public static void main(String [] args)
{
try
{
aMethod(0);
}
catch (Exception ex)
{
System.out.printf("exception in main");
}
System.out.printf("finished");
}
}


解析:i / 10;无论i是多少,永远不会抛出异常,所以catch语句不会执行。而finally语句是必定执行的语句。所以先指向aMathod()的finally代码块,输出finally然后执行main()方法的最后一条输出语句,输出finished。
44、

import java.lang.reflect.*;
public class DumpMethods{
public static void main(String[] args) {
try {
Class c=Class.forName(args[0]);
Method m[]=c.getDeclaredMethods(); //返回类或接口声明的所有方法,包括public, protected, default (package) 访问和private方法的Method对象,但不包括继承的方法。当然也包括它所实现接口的方法。
for (int i = 0; i < m.length; i++) {
System.out.println(m[i].toString());
}
} catch (Throwable e) {
System.err.println(e);
}
}
}


解析:public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。 public Method[]getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
45、PreparedStatement子接口:CallableStatement(用于执行 SQL 存储过程的接口)
Statement的子接口:PreparedStatement
46、jsp分页步骤:
1、count(*)得到总记录数
2、计算总页数
3、获取所有记录(个人感觉这一步不需要,可以直接获取指定页数数据)
4、过滤显示本页数据
47、代码输出:///MyClass.class
public static void main (String[] args) { 
String classFile = "com. jd. ". replaceA11(".", "/") + "MyClass.class";
System.out.println(classFile);
}


解析:由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/"。如果想替换的只是".",那么久要写成"\\.".
48、代码输出:3423
public class TestDemo { 
public static String output =""; 
public static void foo(int i){ 
  try{ 
  if(i == 1){ 
 throw new Exception(); 
  } 
  }catch(Exception e){ 
  output += "2"; 
  return ; 
  }finally{ 
  output += "3"; 
  } 
  output += "4"; 
} 

public static void main(String[] args) { 
  foo(0); 
  foo(1); 
  System.out.println(output);
} 
}


解析:第一次try没执行,所以没有异常抛出,程序继续,finally必须执行,try外部代码执行,output=“34”
          第二次try执行,抛出异常,程序中断,执行catch,最后执行finally,程序结束,所以output=3423“
49、以下JSP代码定义了一个变量,如何输出这个变量的值?<bean:define id="stringBean" value="helloWorld"/>
    (1)<%=stringBean%>            (2)<bean:write name="stringBean"/>
(3)<%String myBean=(String)pageContext.getAttribute("stringBean",PageContext.PAGE_SCOPE);%>
<%=myBean%>
50、final修饰类、方法、属性!不能修饰抽象类,因为抽象类一般都是需要被继承的,final修饰后就不能继承了。
    final修饰的方法不能被重写而不是重载! 
51、重载是在同一个类中,有多个方法名相同,参数列表不同(参数个数不同,参数类型不同),与方法的返回值无关,与权限修饰符无关

(未完待续)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bboyzqh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值