Java面试相关---知识点精简(一)

JDK基础

JDK,JRE,JVM的作用及关系(掌握)

  • 作用
    • JVM:保证Java语言跨平台
    • JRE:Java程序的运行环境
    • JDK:Java程序的开发环境
  • 关系
    • JDK:JRE+工具
    • JRE:JVM+类库

java常识

关键字

  • 被Java语言赋予特定含义的单词
  • 特点:
    全部小写。
  • 注意事项:goto和const作为保留字存在。

标识符

  • 就是给类,接口,方法,变量等起名字的字符序列

    • 组成规则:
      A:英文大小写字母
      B:数字
      C:$和_
    • 注意事项:
      A:不能以数字开头
      B:不能是java中的关键字
      C:区分大小写

数据类型

基本数据类型

    A:整数            占用字节数
        byte            1
        short            2
        int             4
        long            8
    B:浮点数
        float            4
        double            8
    C:字符
        char            2
    D:布尔
        boolean            1

注意:
整数默认是int类型,浮点数默认是double。
长整数要加L或者l。
单精度的浮点数要加F或者f。

数据转换

默认转换

    A:从小到大
    B:byte,short,char -- int -- long -- float -- double
    C:byte,short,char之间不相互转换,直接转成int类型参与运算。、

请自己实现两个整数变量的交换,不用第三个变量

用位异或实现
因为:aba=b.一个数异或两次等于同一个数
int a=10,int b=10;
a=a^b;
b=a^b;
a=a^b;

用变量相加的做法
a=a+b;
b=a-b;
a=a-b;

一句话搞定
b=(a+b)-(a=b)

请用最有效率的方式计算出2乘以8的结果

2<<3

代码块

  • 用{}括起来的代码。
  • 分类:
    • 局部代码块
      用于限定变量的生命周期,及早释放,提高内存利用率。
    • 构造代码块
      把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块。
    • 静态代码块
      对类的数据进行初始化,仅仅只执行一次。
  • 静态代码块,构造代码块,构造方法的顺序问题?
    静态代码块 > 构造代码块 > 构造方法

面向对象

  • 成员变量和局部变量的区别
    • 位置不同
    • 内存中位置不同
    • 生命周期不同
    • 初始化值不同

继承

高内聚低耦合,类里面单独实现方法,类与类之间减少关联就是低耦合

虽然子类中构造方法默认有一个super()
初始化的时候,不是按照那个顺序进行的。
而是按照分层初始化进行的。
它仅仅表示要先初始化父类数据,再初始化子类数据。

多态

多态中的成员访问特点

  • 成员变量
    编译看左边,运行看左边
  • 构造方法
    子类的构造都会默认访问父类构造
  • 成员方法
    编译看左边,运行看右边
  • 静态方法
    编译看左边,运行看左边

为什么?
因为成员方法有重写。

接口

接口的成员特点:
  • 成员变量
    只能是常量
    默认修饰符:public static final
  • 构造方法
    没有构造方法
  • 成员方法
    只能是抽象的
    默认修饰符:public abstract

内部类

成员内部类常见修饰符号

  • private 为了数据的安全性
  • static 为了访问的方便性

成员内部类不是静态的:

外部类名.内部类名 对象名 = new 外部类名.new 内部类名();

成员内部类是静态的:

外部类名.内部类名 对象名 = new 外部类名.内部类名();

局部内部类

  • 可以直接访问外部类成员
  • 在局部位置,可以创建内部类对象,通过对象调用内部类方法
面试题:

局部内部类访问局部变量必须使用final修饰为什么呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失。而堆内存的内容并不会立即消失,所以我们加final修饰,加入final修饰后,变量就变成了常量,既然是常量,你消失了,我在内存中存储的是数据数值,还是有数据可以使用。

匿名内部类

本质:是一个继承了该类或者实现了该接口的子类匿名对象
在Android开发中用的多,因为匿名内部类用完就是垃圾等待回收。不过它只能用一次。

API

Object

  • toString()
    返回对象的字符串表示,默认是由类的全路径+'@'+哈希值的十六进制表示。
    这个表示其实是没有意义的,一般子类都会重写该方法。
    如何重写呢?过程我也讲解过了,基本上就是要求信息简单明了。
    但是最终还是自动生成。
  • equals()
    比较两个对象是否相同。默认情况下,比较的是地址值是否相同。
    而比较地址值是没有意义的,所以,一般子类也会重写该方法。
    重写过程,我也详细的讲解和分析了。
    但是最终还是自动生成。
  • hashCode() 返回对象的哈希值。不是实际地址值,可以理解为地址值。
  • getClass() 返回对象的字节码文件对象,反射中我们会详细讲解
  • finalize() 用于垃圾回收,在不确定的时间
  • clone() 可以实现对象的克隆,包括成员变量的数据复制,但是它和两个引用指向同一个对象是有区别的。
  • 直接输出一个对象名称,其实默认调用了该对象的toString()方法。

面试题

==和equals()的区别?

  • ==
    基本类型:比较的是值是否相同
    引用类型:比较的是地址值是否相同
  • equals()
    只能比较引用类型。默认情况下,比较的是地址值是否相同。
    但是,我们可以根据自己的需要重写该方法。

Scanner

Scanner scan=new Scanner(System.in);
通过这个对象先获取一个数值,在获取一个字符串,会出现问题
如下:

int i=scan.nextInt();
String s=scan.nextLine();

主要原因是:是换行符的问题。/r/n
如何解决

  1. 重新获取一个键盘录入对象
  2. 把所有类型转换成字符串类型,在转换回来。

String类(最常见的没有之一)

字符串的特点

  • 一旦被赋值就不能被改变这里的值指的是数值而不是引用。
  • 字符串直接赋值的方式是先到字符串常量池里面去找,如果有直接返回,没有就创建并返回
  • 字符串拼接,如果是常量相加先拼接然后再常量池中找,如果有直接返回否则创建。如果有变量拼接就是先开空间在拼接。

compareTo()字符串比较

public int compareTo(String anotherString)。按字典顺序比较,可以看源码看返回结果是什么。

String s=new String("Hello")和String s="Hello";的区别

  • 前者创建两个或一个对象。
  • 后者创建一个或零个对象

StringBuffer

线程安全---同步(有人操作时其他不能操作)--数据安全

StringBuffer和String的区别

前者长度可变,后者不可变
如果前者用字符串拼接,不会浪费太多的空间
他们都可以通过互相的构造方法转换成相互的对象,

StringBuffer.toString()也可转换成字符串.任何一个引用类型都可以通过toString转成String对象。

StringBuffer和StringBuilder

StringBuilder是线程不安全,效率高

StringBuffer和数组的区别

二者都可以看成一个容器,装其他数据。但是stringBufer的数据最终是一个字符串数据。而数组可以放置多种数据,但必须同一种数据类型。

Arrays

针对数组进行操作的工具类。里面有一系列方法对数组进行操作。

包装类

Integer类:下面两句代码做了哪些事情?
Integer i=1;//自动装箱,相当于Integer.valueOf(1)
i+=1;//自动拆箱在自动装箱

面试题

Integer i1=127;
Integer i2=127;
System.out.println(i1==i2);
Integer i3=128;
Integer i4=128;
System.out.println(i3==i4);
第一个输出语句为true.第二个为false
通过查看valuof这个源码,我们就知道了,针对-128到127之间的数据,做了一个数据缓存池,如果数据是该范围的,每次并不创建新的空间。

注意:Integer的数据直接赋值,如果在-128到127直接按,会直接冲缓冲池里获取数据

Random:产生随机数

public Random();没有给种子,用的是默认种子,是当前时间的毫秒值
public Random(long seed);给出指定种子(给定了种子之后,每次产生的随机数相同)

System

System 类包含一些有用的类字段和方法。它不能被实例化

System.gc()垃圾回收机制

System.gc()可用于垃圾回收。当使用System.gc()回收某个对象所占用的内存之前,通过要求程序调用适当的方法来清理资源。在没有明确指定资源清理的情况下,Java提高了默认机制来清理该对象的资源,就是调用Object类的finalize()方法。finalize()方法的作用是释放一个对象占用的内存空间时,会被JVM调用。而子类重写该方法,就可以清理对象占用的资源,该方法有没有链式调用,所以必须手动实现。
从程序的运行结果可以发现,执行System.gc()前,系统会自动调用finalize()方法清除对象占有的资源,通过super.finalize()方式可以实现从下到上的finalize()方法的调用,即先释放自己的资源,再去释放父类的资源。
但是,不要在程序中频繁的调用垃圾回收,因为每一次执行垃圾回收,jvm都会强制启动垃圾回收器运行,这会耗费更多的系统资源,会与正常的Java程序运行争抢资源,只有在执行大量的对象的释放,才调用垃圾回收最好

arraycopy(命名不规范的一个方法)

从指定数组中复制一个数组,复制从指定的位置开始,到目标位置结束。

正则表达式

符合一定规则的字符串。相关的类Pattern(在API中我们可以查看)

  • 字符

    • x 字符 x。举例:'a'表示字符a
    • \ 反斜线字符。两个\才能代表一个因为\具有转义功能
    • \n 新行(换行)符 ('\u000A')
    • \r 回车符 ('\u000D')
  • 字符类

    • [abc] a、b 或 c(简单类)
    • [^abc] 任何字符,除了 a、b 或 c(否定)
    • [a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
    • [0-9] 0到9的字符都包括
  • 预定义字符类

    • . 任何字符。我的就是.字符本身,怎么表示呢? .使用的时候是\.
    • \d 数字:[0-9]。但是我们使用的时候必须\d
    • \w 单词字符:[a-zA-Z_0-9]
      在正则表达式里面组成单词的东西必须有这些东西组成
  • 边界匹配器

    • ^ 行的开头
    • $ 行的结尾
    • \b 单词边界
      就是不是单词字符的地方。
      举例:hello world?haha;xixi
  • Greedy 数量词

    • X? X,一次或一次也没有
    • X* X,零次或多次
    • X+ X,一次或多次
    • X{n} X,恰好 n 次
    • X{n,} X,至少 n 次
    • X{n,m} X,至少 n 次,但是不超过 m 次

推荐阅读更多精彩内容