Java面试准备

1.HashSet子类依靠()方法区分重复元素

hashcode(),equals()方法
HashSet的底层还是用HashMap来实现的。将Entry<K,V>的V都变成了同一个Object对象,public static final PRESENT = new Object()。
而HashMap的数据结构是数组+链表+红黑树。
调用K的hashCode方法,然后高低16位进行&运算。得到的hash值,与数组tab[](桶)的长度-1进行&运算,确定插入对象在哪一个桶上。然后调用对象的equals方法,形成链表。当链表长度大于8时,链表转红黑树。

2。java的jvm内存

栈区:
每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
堆区:
存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
方法区:
又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

3.Java中对于文本文件和二进制文件,都可以当作二进制文件进行操作。

4.面向对象的五个基本原则:

单一职责原则(Single-Resposibility Principle):一个类,最好只做一件事,只有一个引起它的变化。单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。
开放封闭原则(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。
Liskov替换原则(Liskov-Substituion Principle):子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。
依赖倒置原则(Dependecy-Inversion Principle):依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。
接口隔离原则(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口

5.java字节字符流

字节流:
InputStream
|-- FileInputStream (基本文件流)
|-- BufferedInputStream
|-- DataInputStream
|-- ObjectInputStream
字符流
Reader
|-- InputStreamReader (byte->char 桥梁)
|-- BufferedReader (常用)
Writer
|-- OutputStreamWriter (char->byte 桥梁)
|-- BufferedWriter
|-- PrintWriter (常用)

6.abstrct抽象类

1、abstract类不能用来创建abstract类的对象;
2、final类不能用来派生子类,因为用final修饰的类不能被继承;
3、如2所述,final不能与abstract同时修饰一个类,abstract类就是被用来继承的;
4、类中有abstract方法必须用abstract修饰,但abstract类中可以没有抽象方法,接口中也可以有abstract方法。
abstract是用来修饰类和方法的:
1. 修饰方法:abstract不能和private、final、static共用。
2. 修饰外部类:abstract不能和final、static共用。(外部类的访问修饰符只能是默认和public)
3. 修饰内部类:abstract不能和final共用。(内部类四种访问修饰符都可以修饰)

7.内部类

8,int 是八大基本数据类型之一

(byte,char,short,int,long,float,double,boolean)
Integer 是 int 包装类;
int是基本数据类型,默认值为0,
Integer 是类,默认值为null;
Integer 表示的是对象,用一个引用指向这个对象,
int是基本数据类型,直接存储数值。

9.Jvm加载类

一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:
1.Bootstrap ClassLoader 负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、2.resources.jar、charsets.jar和class等
3.Extension ClassLoader 负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
4.App ClassLoader 负责加载当前java应用的classpath中的所有类。
classloader 加载类用的是全盘负责委托机制。 所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。
所以,当我们自定义的classlo ader加载成功了 com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成

10.后端获取数据

,向前端输出的过程中,输出前应该采用信息安全部发布的XSSFilter进行相应编码。

11。Servlet生命周期分为三个阶段:

1.初始化阶段 调用init()方法
2.响应客户请求阶段  调用service()方法
3.终止阶段  调用destroy()方法
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客户。

12 HTTP的操作

A:设置HTTP头标
response.setHeader(“Refresh”,“3”); //三秒刷新页面一次
B:设置cookie
Cookie c1 = new Cookie(“username”,“only”);
response.addCookie(c1);
C(错误):读取路径信息,request读取路径信息
从request获取各种路径总结
request.getRealPath(“url”); // 虚拟目录映射为实际目录
request.getRealPath("./"); // 网页所在的目录
request.getRealPath("…/"); // 网页所在目录的上一层目录
request.getContextPath(); // 应用的web目录的名称
D:输出返回数据
HttpServleteResponse.getOutputStream().write();

13.JDK收集器

1.Serial收集器
单线程收集器,收集时会暂停所有工作线程(我们将这件事情称之为Stop The World,下称STW),使用复制收集算法,虚拟机运行在Client模式时的默认新生代收集器。
2.ParNew收集器
ParNew 收集器就是Serial的多线程版本,除了使用多条收集线程外,其余行为包括算法、STW、对象分配规则、回收策略等都与Serial收集器一摸一样。对 应的这种收集器是虚拟机运行在Server模式的默认新生代收集器,在单CPU的环境中,ParNew收集器并不会比Serial收集器有更好的效果。
3.Parallel Scavenge收集器
Parallel Scavenge收集器(下称PS收集器)也是一个多线程收集器,也是使用复制算法,但它的对象分配规则与回收策略都与ParNew收集器有所不同,它是 以吞吐量最大化(即GC时间占总运行时间最小)为目标的收集器实现,它允许较长时间的STW换取总吞吐量最大化。
4.Serial Old收集器
Serial Old是单线程收集器,使用标记-整理算法,是老年代的收集器,上面三种都是使用在新生代收集器。
5.Parallel Old收集器
老年代版本吞吐量优先收集器,使用多线程和标记-整理算法,JVM 1.6提供,在此之前,新生代使用了PS收集器的话,老年代除Serial Old外别无选择,因为PS无法与CMS收集器配合工作。
6.CMS(Concurrent Mark Sweep)收集器
CMS 是一种以最短停顿时间为目标的收集器,使用CMS并不能达到GC效率最高(总体GC时间最小),但它能尽可能降低GC时服务的停顿时间,这一点对于实时或 者高交互性应用(譬如证券交易)来说至关重要,这类应用对于长时间STW一般是不可容忍的。CMS收集器使用的是标记-清除算法,也就是说它在运行期间会 产生空间碎片,所以虚拟机提供了参数开启CMS收集结束后再进行一次内存压缩。

14.String, StringBuffer,StringBuilder的区别

java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

1.可变与不可变

String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。
private final char value[];
String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
char[] value;
StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer();
不能通过赋值符号对他进行付值. , 如 sb = “welcome to here!”;//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法. sb.append(“hello”);

2.是否多线程安全

String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码:

public synchronized StringBuffer reverse() {
super .reverse();
return this ;
}

public int indexOf(String str) {
return indexOf(str, 0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法
}

StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的 。

3.StringBuilder与StringBuffer共同点

StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。
抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高

15.JDBC的sql连接数据库的过程

1.加载驱动
在连接数据库之前,需要加载数据库的驱动到JVM(Java虚拟机),这需要通过java.lang.Class类的静态方法forName(String className)实现.
例如:
//加载Oracle的驱动
try{
Class.forName(“oracle.jdbc.OracleDriver”);
}catch(ClassNotFoundException e){
System.out.println(“找不到程序驱动类,加载驱动失败!”);
e.printStackTrace();
}
加载成功后,会将驱动类的实例注册到DriverManager类中。
2.提供JDBC连接的URL
jdbc:oracle:thin:@192.168.31.50:1521:orcl
3.创建数据库的连接
想连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
使用DriverManager的getConnection(url,uname,upass)传入数据库的路径,用户名,密码获得一个连接
Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@192.168.31.50:8080:orcl”,“uname”,“upass”);
4.创建一个Statement
要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:
1.执行静态语句,通常通过Statement实例实现。
Statement st = conn.createStatement();
2.执行动态语句,通常通过PreparedStatement实现。
PreparedStatement ps = conn.prepareStatement(sql);
3.执行数据库存储过程.通常通过CallableStatement实现
CallableStatement cs = conn.prepareCall("{CALL demoSp(?,?)}");
5.执行sql语句
ResultSet executeQuery(sql) 适用于遍历多个结果,插入集合,返回一个结果集,可以用.next对该对象进行遍历,使用getString(“字段名”)获取字段值
int executeUpdate(sql) 适用于Update,insert或delete语句以及sqlDDL语句,例如建表和删表等等,返回被改变的条数
6.关闭JDBC对象
关闭顺序要和声明顺序相反
1.关闭记录集
2.关闭声明
3.关闭连接对象
if(rs != null){
rs.close();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值