八股文 --- java基础(一)

语言的特点

java是一个面向对象, 支持多线程, 具有可靠性和安全性以及高效性的语言, 编译与解释并存

编译型编译型语言会通过编译器

会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。

JDK与JRE, JVM和JIT 还有 AOT

JDK和JRE

JDK供开发者使用, JRE是java运行时环境

  • JDK包含JRE, 还有其他编译java源码的编译器
  • 编写和编译java程序需要JDK
  • 对于某些需要使用 Java 特性的应用程序,如 JSP 转换为 Java Servlet、使用反射等,也需要 JDK 来编译和运行 Java 代码

但是java9后不再区分这两个,
取而代之的是模块系统(JDK 被重新组织成 94 个模块)+ jlink工具

JVM

承载java的虚拟机

JVM能够理解的代码就是字节码

解释器和JIT

java初始是解释型语言,

但是对应常使用的代码会使用编译器JIT进行编译, 在下次执行时立刻使用

JIT是用于编译代码

故java是编译与解释并存的语言

新编译模式AOT

  • JIT是在运行时编译
  • AOT是在运行前编译

AOT 更适合当下的云原生场景,对微服务架构的支持也比较友好。
但是不支持Java的一些动态特征

常见的java八种数据类型

  1. byte:字节型,占用1个字节。
  2. short:短整型,占用2个字节。
  3. int:整型,占用4个字节。
  4. long:长整型,占用8个字节。
  5. float:单精度浮点型,占用4个字节。
  6. double:双精度浮点型,占用8个字节。
  7. char:字符型,占用2个字节。
  8. boolean:布尔型,只能取两个值之一:true 或 false。

基本类型和包装类型

Java中包装类型就是对应的数据类型类

Byte、Short、Integer、Long、Float、Double、Character、Boolean 这种

区别:

  • 包装类型可用于泛型, 基本类型不可
  • 包装类型数据属于对象类型, 存储在堆中, 而基本类型数据存储在Java虚拟机栈中[ 大部分 ]
    • 局部变量,存放在栈中;
    • 如果它们是成员变量,存放在堆中
    • static变量存储在堆中
  • 包装类型初始值都是null
  • 对于基本数据类型来说,== 比较的是值。对于包装数据类型来说,== 比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用 equals() 方法。

装箱与拆箱

就是基本类型与包装类型转换

装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。

数据操作

浮点数精度丢失

无限循环小数不会全部存储, 只能截断, 导致精度丢失

[ 二进制下的截断直接导致一位数出现问题 ]

如何解决

BigDecimal 可以实现对浮点数的运算

BigDecimala =newBigDecimal("1.0");

超过long长度的整型数据如何表示

使用BigInteger…

Java变量

成员变量与局部变量区别

  • 局部变量不能使用static
  • 生存周期不同
  • 局部变量存在栈中, 成员变量存在堆中
  • 局部变量没有初始值, 成员变量有

静态变量

  • 被类的所有实例共享
  • 只分配一次内存

arraylist与linklist的区别

这是两种集合, 一个使用数组实现, 一个使用双向链表实现

就是Java中顺序表与链表的实现

方法

静态方法

  • 静态方法不能调用非静态成员

        因为静态方法属于类, 而非静态成员属于对象

  • 静态方法使用 类名. 方法名调用

重载与重写

重载是同类下多个同名方法

重写是继承父类重写方法

重写规则

两同两小一大

  • “两同”即方法名相同、形参列表相同;
  • “两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;
  • “一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等。

可变参数

就是一个方法传入不定个参数

Java对象

对象引用放在栈中

对象实例放在堆中

面向对象三大特征

抽象, 继承, 多态

对象相等与引用相等

  • 对象的相等一般比较的是内存中存放的内容是否相等。
  • 引用相等一般比较的是他们指向的内存地址是否相等。

对象构造方法

在声明对象时带的括号实际上就是调用了构造方法!

  • 构造方法不能被重写, 但是可以重载
    • 就是在子类中新了一个构造方法

抽象类与接口类

  • 均不能实例化
  • 均可以包含抽象方法
  • 只能继承一个类, 但是可以实现多个接口
  • 抽象类可以实现接口

深拷贝与浅拷贝区别

  • 深拷贝: 直接复制一个对象
  • 浅拷贝: 只复制引用, 公用一个在堆中的对象实例

引用拷贝

两个不同引用指向同一个对象

Object类

  • 所有类的父类
  • 自带一些方法
    • Getclass 返回class对象
    • Hashcode 获取对象哈希码
    • Equal 比较相等
    • Clone 克隆当前对象拷贝
    • toString 返回类名字实例的16进制哈希码对应的字符串
    • Wait 暂停子线程执行
    • Finalize 实例被回收时触发的操作

hashcode和equals

Hashcode

Object类的hashcode() 方法是用C++ / C 实现的
[ 就是本地方法, 由JVM虚拟机本地代码实现 ]

重写equal时必须重写hashcode方法:
因为equal比较的就是hashcode值

两个对象相等,他们的hashCode和equals一定相等,但是hashCode相等的两个对象未必相等 [ 要考虑哈希冲突 ]

== 与 equal的区别

 == 可以比较基本数据类型和对象, 而equal只能比较对象

  • 对于基本数据类型来说,== 比较的是值。
  • 对于引用数据类型来说,== 比较的是对象的内存地址。

对应 equal, 每个类都有 equal方法 [ 写在Object类中 ]

  • 如果类没有重写equal方法使用equal等价于使用 == 进行比较, 比较的也是内存地址
  • 类重写了 equals()方法:一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。
    • String的equal() 方法就是被重写过的, 比较的是对象的值

String

String, StringBuffer, StringBuilder的区别

是什么?

他们都是处理字符串的类, 但是存在区别

  • String不可变, 对其的删改会创建一个新的String对象
  • StringBuffer是可变字符串, 线程安全
    • 可以动态修改内容而不会创建新字符串
    • 同步变化, 但是单线程下效率较低
  • StringBuilder是可变字符串, 但线程不安全
    • 不进行同步, 性能较优
    • 多个线程修改同个StringBuilder对象时, 会出现数据不一致现象

StringBuffer如何实现线程同步?

通过类似锁的结果, 避免同步执行

就是使用synchronized 关键字进行修饰, 让不同线程对对象的操作依次进行

Java9 String底层实现由 char[] 变为了 byte[]

更节省内存

字符串拼接

  • 拼接字符串的 "+" 实际上是通过 StringBuilder. append方法实现的
  • 拼接完成后的对象是StringBuilder对象, 再通过 toString() 得到String对象
  • 缺陷:
    • 编译器不会创建单个 StringBuilder 以复用,会导致创建过多的 StringBuilder 对象
    • 直接使用 StringBuilder对象进行拼接就可以解决

Java9以后把 "+" 改为了用动态方法 makeConcatWithConstants() 来实现

String类型变量和 常量的拼接

字符串加final进行拼接和不加final的拼接不一样

两个常量的String相加会直接被优化

在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 常量折叠 [ 就是常量表达式的最终值生成在代码中, 只有在编译期确认的常量才可以 ]

 

String 的equal方法和 Object的equal方法

String中的equal方法被重写过

不再比较对象内存地址, 而是比较字符串值是否相等

字符串常量池

JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。

对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池。

String s1 = new String("test")问题

会创建 一个或者两个 对象!

如果字符串常量池中存在 test 字符串对象, 则只会新建一个对象在堆中

否则会在堆和字符串常量中创建两个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值