Java笔试题解析

1.

在JDK1.8之前HashMap由数组+链表数据结构组成。

在JDK1.8之后HashMap由数组+链表+红黑树数据结构组成。

JDK1.8之前HashMap由数组+链表组成,数组是HashMap的主体,链表则是主要为了解决哈希冲突(两个对象调用的hashCode方法计算的哈希值一致导致计算的数组索引值相同)而存在的。JDK1.8以后在解决哈希冲突后有了较大的变化,当链表长度大于阀值(或者红黑树的边界值,默认为8)并且当前数组长度大于64时,此时索引位置上的所有数据改为使用红黑树存储。

 

HashMap可以用null值和空字符串作为Key,不过只能有一个

 2.

HttpServletResponse接口可以设置HTTP头标、设置cookie、输出返回数据。不能够读取路径信息。

3.

.java 是java程序的源代码文件

.class 不是类的扩展名,JVM并不能直接运行java源文件,需要通过javac将java源文件编译成字节码文件,也就是.class文件,JVM在运行某个类的时候,通过加载指定该.class文件就可以

.exe java可以编写成.exe,虽然是exe文件,但是不代表windows可执行文件

.jar 需要有jdk支持,通过JVM运行,这才是真正的运行包

4.

Servlet的生命周期一般可以用三个方法来表示:

inti():仅执行一次,负责在装载Servlet时初始化Servlet

service():核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。

destory():在停止并且卸载Servlet时执行,负责释放资源

5.

Java Thread中run方法和start方法的区别

(1)start:用start方法来启动线程,是真正实现了多线程,通过调用thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行多线程。

(2)run:run()方法只是类的一个普通方法而已,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可以继续执行下面的代码。

6.

加载驱动方法
1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());

3.System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");

7.

Java有5种方式来创建对象:
  1. 使用 new 关键字(最常用): ObjectName obj = new ObjectName();
  2. 使用反射的Class类的newInstance()方法: ObjectName obj = ObjectName.class.newInstance(); 
  3. 使用反射的Constructor类的newInstance()方法: ObjectName obj = ObjectName.class.getConstructor.newInstance();
  4. 使用对象克隆clone()方法: ObjectName obj = obj.clone(); 
  5. 使用反序列化(ObjectInputStream)的readObject()方法: try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) { ObjectName obj = ois.readObject(); }

8.

ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量。
所以ThreadLocal重要作用并不在于多线程间的数据共享,而是数据的独立。
由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问,
变量被彻底封闭在每个访问的线程中。
9.
switch语句后的控制表达式只能是short、char、int、long整数类型和枚举类型,不能是float,double和boolean类型。String类型是java7开始支持。
switch可以支持byte、short、char、int、Byte、Short、Character、Integer、String和枚举类型的数据
byte、short、char自动转变为int类型,
Byte、Short、Character、Integer--JDK1.5自动拆箱,转变为int类型进行匹配
10.
接口中的成员包括:全局常量和抽象方法。接口中的成员都有固定的修饰符, 成员变量:public static final 成员方法:public abstract 接口中的成员的访问权限都是公共的,接口中可以隐藏不写这些固定的修饰符。接口不可以实例化,只有子类重写了接口中的所有方法后,子类才可以实例化,否则子类还是一个抽象类。子类重写方法的访问权限都是public的。
11.
按位或|
按位且&
按位取反~
按位异或^
----------------------------------
逻辑与&&
逻辑或||
非!
----------------------------------
左移<<:补0,相当于乘以2
右移>>:补符号位,相当于除以2,算数操作符
无符号右移>>>:补0,逻辑操作符
12.

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

2)禁止进行指令重排序。

volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。

而对该变量的修改,volatile并不提供原子性的保证。

由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况

多线程下计数器必须使用锁保护。

 

volatile与synchronized的区别:
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.
13.
在Java中,final可以修饰
1.Class:定义一个不能被继承(non-inherited)的类
2.Method:定义一个不能被覆盖(non-overrided)方法
3.Variable:定义一个常量(constant)
14.
Class.forName("com.mysql.jdbc.Driver");  //加载jdbc驱动
con=DriverManager.getConnection(url,user,password); //建立连接
stmt=con.createStatement(); //创建语句执行者(stateMent用于执行不带参数的简单sql语句,PreparedStatement用于执行带参数的预编译sql语句能够预防sql注入,CallableStatement提供了一种标准形式的调用存储过程的方法)
stmt.execute(“sql语句”); 
rs=stmt.executeQuery("sql查询语句"); //结果集
15.

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

posted @   白非立  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示