Java 面试之语言基础

Java八种基本数据类型

类 型大小封 装 类
boolean1字节Boolean
char2字节Character
byte1字节Byte
short2字节Short
int4字节Integer
long8字节Long
float4字节Float
double8字节Double

Java面向对象(四个基本特性)

  1. 封装:将客观事物包装成类,隐藏具体实现,提供操作接口。
  2. 抽象:用代码描述客观事物。包括数据抽象(属性)和过程抽象(行为)。
  3. 继承:子类获得父类的属性和行为(extends)。
  4. 多态:同一行为多种表现形式。
    • 重写Override
    • 接口的不同实现implements
    • 抽象类和抽象方法abstract

Java与C++对比

比较点JavaC++
面向对象思想完全对象化可采用非面向对象(兼容C)
内存管理机制Java自身管理程序员管理
异常机制完善欠缺
第三方库丰富(Log、JUnit等等)较少(STL)
执行效率
操控底层麻烦方便

Java 8新特性

  • 默认方法:在接口里面有了一个实现的方法
  • Lambda 表达式:Lambda允许把函数作为一个方法的参数
  • Stream API:把真正的函数式编程风格引入到Java中
  • 方法引用:可以直接引用已有Java类或对象的方法或构造器
  • Date Time API:加强对日期与时间的处理
  • Optional 类:Optional 类已成为 Java 8类库的一部分,用来解决空指针异常
  • 新编译工具:Nashorn引擎(一个新的JavaScript引擎)、 类依赖分析器

Java反射机制

  在运行状态中,对于任意一个类,都能够知道其所有属性和方法;对于任意一个对象,都能够调用其任意方法和属性。这种动态获取信息及动态调用对象方法的功能称为Java语言的反射机制。Java反射API如下:

  • Class:反射的核心类。
  • Field:类的成员变量。
  • Method:类的成员方法。
  • Constructor:类的构造方法。
/**获取Class对象的三种方式**/

// 1. 调用某个对象的getClass()方法
Class clazz = person.getClass();

// 2. 调用某个类的class属性
Class clazz = Person.class;

// 3. 使用Class类的forName()静态方法
Class clazz = Class.forName("Person");

  反射机制主要提供了以下功能:

  1. 在运行时判断任意一个对象所属的类。
  2. 在运行时构造任意一个类的对象。
  3. 在运行时判断任意一个类所具有的成员变量和方法。
  4. 在运行时调用任意一个对象的方法。
  5. 生成动态代理。

Java异常机制

Error与Excption包结构

  1. Error:程序无法处理的错误,继承自Throwable。

  2. Exception:程序可以处理的异常,继承自Throwable。
    1. Checked Exception:受检异常,需要强制catch,是Exception的子类。
    2. Unchecked Exception:不受检异常,无需强制catch,是RuntimeException的子类。

    例如list.size()语句,若list为null,则会出现NullPointerException(Unchecked Exception)

if (ex instanceof RuntimeException){
    // ex is unchecked exception
} else if (ex instanceof Exception){
    // ex is checked exception
} else {
    // ex is a error
}

Throwable体系

各种比较

Override和Overload的区别

比较点OverrideOverload
中文重写重载
方法名相同相同
形参相同不同
返回类型相同可同可不同

Override 典型例子:接口方法的重写
Overload 典型例子:构造方法的重载

Interface与abstract类的区别

比较点Interfaceabstract类
中文接口抽象类
能否实例化不能不能
方法能否实现Java 8 可以可以
一个类可以implements多个extends一个

equals()与==的区别

  equals()用于比较对象(内容),==常用于比较原生类型(地址)。简单的说,==比较两个人的DNA,equals()一般用来比较两个人身高体重等等,可自定义。

int x = 10;
int y = 10;
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");

// == 比较两个(基本数据类型)地址值
System.out.println(x == y); // true
System.out.println(str1 == str2); // true
System.out.println(str3 == str4); // false

// String重写的equals()比较两个对象内容
System.out.println(str1.equals(str2)); // true
System.out.println(str3.equals(str4)); // true

要注意Object类中equals()即为==equals()是可以重写(Override)的。

String、StringBuffer、StringBuilder

比较点StringStringBufferStringBuilder
底层实现final char value[]char[] valuechar[] value
可变性(参考底层)不可变可变可变
修改时不会改变自身改变自身改变自身
安全性线程安全线程安全非线程安全
使用场景少量数据多线程大量数据单线程大量数据
String str = "abc"; // str只是一个String对象的引用
str = "xyz"; // 创建了新对象"xyz",而引用str重新指向新对象

强弱软虚四种引用

比较点强引用软引用弱引用虚引用
特性不会被回收内存足则不回收,内存不足则回收一旦发现便回收必须和引用队列联合使用
使用场景平时工作接触的最多(new)可用来实现内存敏感的高速缓存常用于Map数据结构中,引用占用内存空间较大的对象跟踪对象被回收的活动

comparable接口和comparator接口

  • Comparable:在集合内部实现排序的接口,位于java.lang包。
  • Comparator:在集合外部实现排序的比较器接口,位于java.util包。
public class Person implements Comparable {
    String name;
    int age;
    
    @Override
    public int compareTo(Object o) {
        // 使用字符串的比较
        int i = name.compareTo(((Person) o).name); 
        
        if (i == 0) { // 如果名字一样,比较年龄, 返回比较年龄结果
            return age - ((Person) o).age;
        } else {
            return i; // 名字不一样, 返回比较名字的结果.
        }
    }
}

//使用Collections.sort(personList)即可排序
public class Person {
    String name;
    int age;

    static class PersonComparator implements Comparator {
        @Override
        public int compare(Object o1, Object o2) {
            // 使用字符串的比较
            int i = ((Person) o1).name.compareTo(((Person) o2).name); 
            
            if (i == 0) { // 如果名字一样,比较年龄,返回比较年龄结果
                return ((Person) o1).age - ((Person) o2).age;
            } else {
                return i; // 名字不一样, 返回比较名字的结果.
            }
        }
    }
}

//使用Collections.sort(list, new Person.PersonComparator())即可排序

Arrays内使用双轴快排(DualPivotQuicksort),两个中心点三段数据。

IO,BIO,NIO,AIO

  Java中IO是以流为基础进行输入输出的,在网络编程中,接触到最多的就是利用Socket进行网络通信开发,主要有BIO、NIO、AIO三种实现方式。

比较点BIONIOAIO
中文阻塞IO非阻塞IO异步IO
版本JDK 1.4提出JDK 1.7 提出
描述服务端每次都需要创建一个线程来建立连接并处理消息。若建立连接、读写数据时发生阻碍,线程会阻塞。并发情况下,N个连接需要N个线程来处理。使用一个线程来管理所有的Socket 通道,也就是基于Selector机制,查询到事件时(连接、读写),转发给不同的处理线程(Handler)。在进行读写操作时,只需要调用相应的read/write方法,并传入CompletionHandler(动作完成处理器),在动作完成后会调用CompletionHandler。

序列化与反序列化

  序列化即把对象转换为字节序列;反序列化即把字节序列恢复为对象。其使用场景大致有如下几种:

  • 把内存中的对象状态保存到文件或者数据库中。
  • 用套接字在网络上传送对象。
  • 通过RMI传输对象。

JVM会把字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化。

哪些情况会导致OOM或SOF,怎么解决

OutOfMemory(OOM)

  • Java堆溢出:一般由于内存泄露或者堆的大小设置不当引起。可以通过虚拟机参数-Xms-Xmx等设置堆大小。
  • 方法区溢出:包括运行时常量池溢出,一般由于大量动态生成的Class导致。可以通过-XX:PermSize-XX:MaxPermSize限制方法区的大小。

使用JConsole生成Heap Dump文件,然后使用MAT分析排查

StackOverflow(SOF)

  • Java虚拟机栈和本地方法栈内存溢出:一般是由于程序中存在死循环或者深度递归调用造成的,栈设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈大小。

JNI的使用

  JNI (Java Native Interface)允许Java代码和其他语言代码(主要是C和C++)进行交互。

  1. 定义本地native方法
  2. 用javah命令生成.h头文件,拷贝至jni目录
  3. 在jni目录中编写.c文件
  4. 在jni目录中创建Android.mk文件,声明所引用的.c文件和生成的函数库名
  5. 创建Application.mk文件,声明支持的平台(armeabi、armeabi-v7a、x86)
  6. 使用ndk工具编译生成.so成动态链接库文件

天猫超市优惠地址

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值