【Java系列】Java 基础

目录


基础

1.JDK和JRE的区别

JDK:全称Java Development Kit,翻译为Java开发工具包,提供Java的开发和运行环境,是整个Java的核心。目前各大主流公司都有自己的jdk,比如oracle jdk(注意,生产环境使用时需要注意法律风险)、openjdk(目前生产环境主流的jdk)、dragonwell(阿里家的jdk,在金融电商物流方面做了优化)、zulujdk(巨硬家的jdk)等等

JRE:全称Java Runtime Environment,Java运行时环境,为Java提供运行所需的环境

总的来说,JDK包含JRE,JAVA源码的编译器javac,监控工具jconsole,分析工具jvisualvm

总结,如果你需要运行Java程序(类似我的世界那种),只需要安装JRE;如果你需要程序开发,那么需要安装JDK就行了,不需要再重复安装JRE。

2.Java为什么不直接实现lterator接口,而是实现lterable?

Iterator是迭代器类,而Iterable是接口。好多类都实现了Iterable接口,这样对象就可以调用iterator()方法。

看一下JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。仔细想一下这么做是有道理的。

因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。

当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。

除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。

但即时这样,Collection也只能同时存在一个当前迭代位置。而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。多个迭代器是互不干扰的。

3.简述什么是值传递和引用传递?

复制代码
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。
引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。

4.概括的解释下Java线程的几种可用状态?

线程在执行过程中,可以处于下面几种状态:

1 就绪(Runnable):线程准备运行,不一定立马就能开始执行。

2 运行中(Running):进程正在执行线程的代码。

3 等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。

4 睡眠中(Sleeping):线程被强制睡眠。

5 I/O阻塞(Blocked on I/O):等待I/O操作完成。

6 同步阻塞(Blocked on Synchronization):等待获取锁。

7 死亡(Dead):线程完成了执行。"

中级

1.简述Java同步方法和同步代码块的区别 ?

区别:

同步方法默认用this或者当前类class对象作为锁;

同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法;

同步方法使用关键字 synchronized修饰方法,而同步代码块主要是修饰需要进行同步的代码,用 synchronized(object){代码内容}进行修饰;

【为何使用同步?】

java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(增删改查),将会导致数据的不准确,相互之间产生冲突。类似于在atm取钱,银行数据确没有变,这是不行的,要存在于一个事务中。因此加入了同步锁,以避免在该线程没有结束前,调用其他线程。从而保证了变量的唯一性,准确性。

1.同步方法:

即有synchronized (同步,美 'sɪŋkrənaɪzd ) 修饰符修饰的方法。

由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用给方法前,要获取内置锁,否则处于阻塞状态。

例:public synchronized getMoney(){}

注:synchronized修饰静态方法,如果调用该静态方法,将锁住整个类。

2.同步代码块

即有synchronized修饰符修饰的语句块,被该关键词修饰的语句块,将加上内置锁。实现同步。

例:synchronized(Object o ){}

同步是高开销的操作,因此尽量减少同步的内容。通常没有必要同步整个方法,同步部分代码块即可。

同步方法默认用this或者当前类class对象作为锁。

同步代码块可以选择以什么来加锁,比同步方法要更颗粒化,我们可以选择只同步会发生问题的部分代码而不是整个方法

2.HashMap和Hashtable有什么区别?

📌 试题回答参考思路:

HashMap和Hashtable区别:

1:HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:

2:HashMap允许键和值是null,而Hashtable不允许键或者值是null。

3:Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。

4:HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。

5:一般认为Hashtable是一个遗留的类。

3.简述Java堆的结构? 什么是堆中的永久代(Perm Gen space)?

📌 试题回答参考思路:

1:堆结构

JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。

堆内存是由存活和死亡的对象组成的。

存活的对象是应用可以访问的,不会被垃圾回收。

死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前,他们会一直占据堆内存空间。

2:永久代(Perm Gen space)

永久代主要存在类定义,字节码,和常量等很少会变更的信息。并且永久代不会发生垃圾回收,如果永久代满了或者超过了临界值,会触发完全垃圾回收(Full Gc)

永久代中一般包含:

类的方法(字节码...)

类名(Sring对象)

.class文件读到的常量信息

class对象相关的对象列表和类型列表 (e.g., 方法对象的array)

JVM创建的内部对象

JIT编译器优化用的信息

而在java8中,已经移除了永久代,新加了一个叫做元数据区的native内存区。

3:元空间

元空间和永久代类似,都是对JVM中规范中方法的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存的限制。类的元数据放入native memory,字符串池和类的静态变量放入java堆中。这样可以加载多少类的元数据就不再由MaxPermSize控制,而由系统的实际可用空间来控制。

4:采用元空间而不用永久代的原因:

为了解决永久代的OOM问题,元数据和class对象存放在永久代中,容易出现性能问题和内存溢出。

类及方法的信息等比较难确定其大小,因此对于永久代大小指定比较困难,大小容易出现永久代溢出,太大容易导致老年代溢出(堆内存不变,此消彼长)。

永久代会为GC带来不必要的复杂度,并且回收效率偏低。

4.简述 Dubbo 和 Spring Cloud 有什么区别 ?

📌 试题回答参考思路:

SpringCloud与Dubbo的区别:

1:两者都是现在主流的微服务框架,但却存在不少差异:

2:初始定位不同:SpringCloud定位为微服务架构下的一站式解决方案;Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用和治理

3:生态环境不同:SpringCloud依托于Spring平台,具备更加完善的生态体系;而Dubbo一开始只是做RPC远程调用,生态相对匮乏,现在逐渐丰富起来。

4:调用方式:SpringCloud是采用Http协议做远程调用,接口一般是Rest风格,比较灵活;Dubbo是采用Dubbo协议,接口一般是Java的Service接口,格式固定。但调用时采用Netty的NIO方式,性能较好。

组件差异比较多,例如SpringCloud注册中心一般用Eureka,而Dubbo用的是Zookeeper

5:SpringCloud生态丰富,功能完善,更像是品牌机,Dubbo则相对灵活,可定制性强,更像是组装机。相关资料:

6:SpringCloud:Spring公司开源的微服务框架,SpirngCloud 定位为微服务架构下的一站式解决方案。

7:Dubbo:阿里巴巴开源的RPC框架,Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断

高级

1.为什么集合类没有实现Cloneable和Serializable接口?

📌 试题回答参考思路:

1.Cloneable接口作用是将一个对象的属性值复制给另一个对象,而不是对象的一个引用。

2.Serializable接口作用(这个罗嗦一下)

序列化的用途

1.有时候,如果想让一个对象持久的存储下来(存到磁盘),或者是进行远程的对象调用,那就要使用序列化实现这些作用。我们必须对所有支持持久化存储的类实现Serializable接口,读取的时候也要进行反序列化。

2.对于jvm来说,进行持久化的类必须有个标记,就是实现Serializable接口,关联serialVersionUID,这个变量就是在反序列话中确定用那个类加载这个对象。

3.值得主意的是,持久化的数据都是存在在java堆中,static类型的数据存在在方法区中,不能被持久化。如果不想让某个成员变量持久化,变量前面用transient关键字

4.当然序列化的那个serialVersionUID这个还可以进行自定义

为什么集合类中不实现上面两个接口呢?

其实不难看出,Cloneable是复制对象的,序列化也是针对对象的操作,集合类只是管理对象的一个工具,就好比说list能够线性的管理对象,set集合能够对对象去重等,这些集合类都是针对与为管理对象而产生的。

其实,着两个接口都是针对真是的对象,而不是集合类这样的管理对象的对象。这个从语义上就是集合类的Cloneable接口和Serializable接口

应该又集合中具体的类型实现,而不是又集合类来实现序列化。

假设集合类实现了这两个接口,如果我要生成一个不需要序列化,不需要clone的集合,那么集合类就强行实现,这样有违集合的设计原则。

2.Java中的HashMap的工作原理是什么?

📌 试题回答参考思路:

在 Java 中,HashMap 属于常用的基于哈希表实现的键值对存储结构,它采用了数组+链表/红黑树的方式进行实现。下面将从以下几个方面介绍 HashMap 的实现原理:哈希函数、数组+链表的实现、扩容机制。

一、哈希函数

HashMap 的核心思想是哈希映射,即将任意长度的输入(即键)通过哈希函数变换成固定长度的输出(即该键在数组中的索引位置),并将该键和值存储到找到的索引位置处。具体来说,哈希函数需要满足以下两个条件:

散列均匀。这意味着不同的键应该有不同的哈希值,并且此哈希值在数组中分布均匀,也就是不要让大量哈希值都集中到一个区域。

计算速度快。为了避免计算哈希值过于缓慢,需要使用高效的哈希函数。

在 Java 中,Java 8 以前使用的是传统的拉链法解决哈希冲突(即多个键映射到同一个数组下标的情况),而 Java 8 之后为了进一步提升性能,采用了链表和红黑树相结合的方式来处理哈希冲突。

二、数组+链表的实现

HashMap 的内部结构是一个数组,数组中每个元素称为桶。桶里放的元素类型是 Entry 类型的对象,该类包含了键和值。当 HashMap 中加入一个键值对时,它会首先根据键获取其哈希码(即通过根据 hash() 方法计算得到),然后通过这个哈希码在数组中找到相应桶,并把键值对存储在桶中。

如果多个键映射到同一索引位置上,就需要通过链表将它们串联起来,而 JDK 1.8 之前版本中采用的则是最基础的链式结构。但随着链表长度的增加,查询效率会逐渐变低,甚至还可能造成链表成环并导致死循环等情况,因此,Java 8 引入了一种新的机制:当链表长度超过阈值(默认为 8)时,会将链表转化为红黑树,以提高查询效率。在使用红黑树优化后,HashMap 的查询性能会更进一步的提升。

系列文章


内容 地址 链接
JAVA介绍 Linux (实战)常用命令

========================================================================= 👊如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容👊


👊 博主很需要大家的支持,你的支持是我创作的不竭动力👊


👊 ~ 点赞收藏+关注 ~👊 =========================================================================

版本记录


  • 2023-10-24 第一版
相关推荐
fangzhanpeng1683 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心5 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u01030552711 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u01030552711 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝12 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552713 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552713 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552716 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552716 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552717 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节