• 【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包含JREJAVA源码的编译器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.简述什么是值传递和引用传递?

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

    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 第一版
  • 相关阅读:
    《Effective Java》知识点(4)--泛型
    HomeAssistant接入天猫精灵
    Vue-2.7自定义指令
    【ffmpeg】音频编码原理
    【专升本】1. 英语考试介绍
    揭开 Amazon Bedrock 的神秘面纱 | 基础篇
    java微博 10 request and response
    网络安全(黑客)自学
    基于python命令流及代码的Plaxis自动化建模
    小程序微信支付实践案例-JAVA
  • 原文地址:https://blog.csdn.net/qq_38517630/article/details/133952135