跳至主要內容

面试-Java

TenSoFlow...大约 10 分钟面试面试-Java

面试-Java

基础

Java八大基本类型

问:Java八大基本类型

答:Byte(1) Short(2) Int(4) Long(8) Float(4) Double(8) Char(2) Boolean(1)

String类中常用的方法

问:String类中常用的方法

答:indexof()从指定字符提取索引位置
replace()替换
subString()截取字符串
equals()比较
split()把字符串分割成字符串数组

为什么要同时重写HashCode和Equals方法

问:为什么要同时重写HashCode和Equals方法

答:官方规定如果两个对象通过equals()方法比较是相等的,那么它们的hashCode()方法必须返回相同的整数值。反之hashCode相同的对象,equals不一定相等。hashCode不同的对象,equals一定不相等。如果只重写一个就会违反这个约定,导致HashMap或HashSet出现重复数据等情况。

String中 == 和equals的区别

问:String中的 == 和equals的区别

答:对于八大基本类型 == 比较的是值,对于引用类型==比较内存地址。
对于引用类型equals默认比较内存地址。
对于String来说 == 比较的是内存地址,equals重写了比较的是内容。

说说Final关键字

问:说说Final关键字

答:Final是一个安全修饰符,Final修饰的类不能被继承,Final声明的方法不能被重写。Final声明的变量不能被修改。

说五个开发中常见的异常

问:说五个开发中常见的异常

答:IO异常
null异常
SQL异常
数组下标越界异常
文件未找到异常

什么是重载和重写

问:什么是重载和重写

答:Java里面方法的重写和重载就是指Java的多态。重写就是父类和子类之间的多态,方法名和参数都一样。重载是一个类中方法的多态,方法名相同而参数不同。

接口和抽象类的异同

问:接口和抽象类的异同

答:
相同点:
接口和抽象类都是抽象的,不能直接实例化,只能被子类实现或继承,并且可以包含抽象方法(没有具体实现),接口和抽象类都用于定义一种规范或者协议,描述类应该具备的行为和功能。
不同点:
接口中的方法都是抽象的,不能有具体的实现;而抽象类中可以包含具体的方法实现,也可以包含抽象方法。Java中一个类只能继承一个父类,但是可以实现多个接口。因此,接口支持多继承,而抽象类不支持多继承。接口中的变量默认是public static final类型的常量,不能被修改;抽象类中可以定义实例变量,并且可以有各种访问控制修饰符。接口中不能包含构造方法;抽象类可以包含构造方法,用于被子类调用。接口主要用于实现类之间的解耦,描述类应该具备的行为,强调规范和契约;而抽象类主要用于作为其他类的基类,提取共性的方法和属性,强调类的继承关系和代码复用。

创建对象的几种方法

问:创建对象的几种方法

答:
第一种:使用new关键字
第二种:通过反射,可以根据类名来创建对象。Class.forName("com.example.MyClass");然后使用Class类的newInstance()方法:该方法会调用类的无参构造方法来创建对象,要求类必须有无参构造函数
第三种:使用clone()方法:通过复制一个现有对象来创建一个新对象,要求被复制的类必须实现Cloneable接口,并且重写clone()方法。

package com.tensoflow;

public class test {

    public static void main(String[] args) throws Exception {
        // 方式一使用new关键字
        A a = new A();
        System.out.println(a.name);

        // 方式二使用反射
        Class<?> aClass = Class.forName("com.tensoflow.A");
        // 调用无参构造创建实例(JDK9+不推荐)
        Object instance = aClass.newInstance();
        // 若需要调用类的方法,需向下转型
        if (instance instanceof A) {
            A aInstance = (A) instance;
            System.out.println(aInstance.name);
        }

        // 方式三使用Clone克隆, A类需要实现CloneAble接口然后重写clone方法
        A clone = (A) a.clone();
        System.out.println(clone.name);

    }
}

什么是反射,能干嘛

问:什么是反射,能干嘛

答:反射就是将类的各个组成部分封装成其它对象。在Java中只要知道类的名字,通过Class.forName方法可以获得到类对象。通过Class类对象就可以获得类的所有信息。比如类中的成员变量和方法。我们可以对类里的这些方法进行执行或者用动态代理模式进行增强。我们常用的Spring和MyBatis框架就是利用Java反射+动态代理的技术编写的。

package com.tensoflow;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射操作 Student 类的完整示例
 */
public class ReflectDemo {
    public static void main(String[] args) {
        try {
            // 获取 Class 对象
            Class<?> studentClass = Class.forName("com.tensoflow.Student");

            System.out.println("=== 1. 获取类基本信息 ===");
            System.out.println("类名:" + studentClass.getName()); // 完整类名
            System.out.println("简单类名:" + studentClass.getSimpleName()); // 仅类名

            System.out.println("\n=== 2. 创建 Student 实例 ===");

            // 调用公有有参构造创建实例
            Constructor<?> publicConstructor = studentClass.getConstructor(String.class, int.class);
            Object student1 = publicConstructor.newInstance("张三", 20);
            System.out.println("有参构造创建的实例:" + student1);

            // 调用私有无参构造创建实例(突破访问权限)
            Constructor<?> privateConstructor = studentClass.getDeclaredConstructor();
            privateConstructor.setAccessible(true); // 关闭访问检查
            Object student2 = privateConstructor.newInstance();
            System.out.println("私有构造创建的实例:" + student2);

            // ===================== 操作字段 =====================
            System.out.println("\n=== 3. 操作字段 ===");

            // 3.1 访问公有字段 age
            Field ageField = studentClass.getField("age");
            ageField.set(student2, 18); // 给 student2 的 age 赋值 18
            System.out.println("student2 的 age 字段:" + ageField.get(student2)); // 18

            // 3.2 访问私有字段 name(突破访问权限)
            Field nameField = studentClass.getDeclaredField("name");
            nameField.setAccessible(true); // 关闭访问检查
            nameField.set(student2, "李四"); // 给 student2 的 name 赋值 李四
            System.out.println("student2 的 name 字段:" + nameField.get(student2)); // 李四

            // 3.3 访问静态字段 school
            Field schoolField = studentClass.getField("school");
            System.out.println("静态字段 school 原值:" + schoolField.get(null)); // 北京大学(静态字段传 null)
            schoolField.set(null, "清华大学"); // 修改静态字段
            System.out.println("静态字段 school 新值:" + schoolField.get(null)); // 清华大学

            // ===================== 4. 调用方法(反射方式) =====================
            System.out.println("\n=== 4. 调用方法 ===");

            // 4.1 调用公有方法 study
            Method studyMethod = studentClass.getMethod("study", String.class);
            studyMethod.invoke(student1, "Java编程"); // 张三 正在学习 Java编程

            // 4.2 调用私有方法 sayHello(突破访问权限)
            Method sayHelloMethod = studentClass.getDeclaredMethod("sayHello", String.class);
            sayHelloMethod.setAccessible(true); // 关闭访问检查
            String result = (String) sayHelloMethod.invoke(student1, "大家好!");
            System.out.println("私有方法返回值:" + result); // [张三]:大家好!

            // 4.3 调用静态方法 printSchool
            Method printSchoolMethod = studentClass.getMethod("printSchool");
            printSchoolMethod.invoke(null); // 学校:清华大学(静态方法传 null)

        } catch (Exception e) {
            // 捕获所有反射相关异常
            e.printStackTrace();
        }
    }
}

类的初始化过程

问:类的初始化过程

答:加载Class文件进内存,在栈内存开辟空间,在堆内存为对象开辟空间,对对象的成员变量进行默认初始化,对对象的成员变量进行显示初始化。通过构造方法对对象的成员变量赋值,把对象地址赋值给变量。

集合

ArrayList的底层

问:ArrayList的底层

答:ArrayList是基于数组实现的,是一个动态数组。底层维护了一个Object类型的数组elementData。如果使用无参构造器,则初始elementData容量为0,第一次添加扩容为10,之后如需再次扩容,则扩容为elementData的1.5倍。如果使用指定大小的构造器则初始elementData容量为指定大小,如果需要扩容,则直接扩容为elementData的1.5倍。另外ArrayList是线程不安全的。

HashMap的底层实现原理

问:HashMap的底层实现原理

答:HashMap的底层是数组+链表+红黑树。数组的初始大小是16,每个数组存储着一个链表。存数据时先根据Key的hashcode值计算出hash值,然后用hash值确定在数组中的位置,如果此位置没有东西则直接放入,如果有就会生成链表,把新的放入链表尾部。当取值时,会先根据Key的hashcode值计算出hash值,确定在数组中的位置,再根据equals方法从该位置上的链表中取出value值。如果数组的长度大于64并且链表的长度大于8就会树化成红黑树。数组扩容倍数是2倍。

项目

Jar包和War包的区别

问:Jar包和War包的区别

答:jar包就是别人写好的一些类,然后对这些类进行打包,开发人员可以将这些jar包引入到自己的项目中,使用这些类和属性。 jar包一般放在lib目录下。war包是一个web模块,可以直接运行,一般开发好的网站,打包后部署到tomcat的网站根目录下,然后重启tomcat,这个包就可以自动解压,相当于代码发布。

四种请求方式

问:四种请求方式

GET
POST
PUT
DELETE

各类默认端口号

问:各类默认端口号

tomcat:8080
MySql: 3306
Redis: 6379
Http:80
Https: 443

Http各类状态码

问:Http各类状态码 1xx 信息性状态码:
100 Continue:服务器已收到请求的一部分,客户端应继续发送剩余部分。
101 Switching Protocols:服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端更改协议。
其他1xx状态码用于协议交互中。

2xx 成功状态码:
200 OK:请求已成功。
201 Created:请求已经被实现,并且创建了新的资源。
204 No Content:服务器成功处理了请求,但没有返回任何内容。

3xx 重定向状态码:
301 Moved Permanently:请求的资源已永久移动到新位置。
302 Found:请求的资源已暂时移动到新位置。
304 Not Modified:客户端发送的请求已经存在且未修改,服务器告诉客户端使用本地缓存版本。

4xx 客户端错误状态码:
400 Bad Request:请求无效。
401 Unauthorized:请求要求用户身份认证。
403 Forbidden:服务器理解请求,但拒绝执行。
404 Not Found:请求的资源未找到。

5xx 服务器错误状态码:
500 Internal Server Error:服务器遇到了一个未知的错误。
502 Bad Gateway:服务器作为网关或代理时收到了无效的响应。
503 Service Unavailable:服务器暂时过载或维护,无法处理请求。
504 Gateway Timeout:服务器作为网关或代理时未及时从上游服务器收到请求。
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8