文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

聊一聊 Java 一些核心知识点

2024-11-28 16:18

关注

Java和C++主要区别有哪些?能不能给我说说优缺点

Java属于半编译、半解释型语言,通过编译器javac生成JVM可识别的字节码(.class)之后,由JVM将其解释成计算机可执行的机器码,所以执行效率相对低,依赖解释器,但是跨平台较好。基于这种情况JVM在后端编译阶段会将那些频繁执行的热点代码(hot spot code)的字节码直接生成机器码直接执行,由此避免频繁编译+解释的步骤:

而C++则是编译型语言,代码通过编译后就可以直接生成机器码直接在服务器上运行,执行速度块、效率高、因为代码是直接服务于针对性的操作系统,所以为了兼容性不得不在逻辑上进行特殊处理,所以跨平台相对差一些。

除此之外java和C++还有以下几个区别:

Java中有了基本类型为什么还需要包装类

java开发是面向对象的,很多特定的操作都需要以对象的维度运行,最典型的就是集合的泛型:

List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);

而且基本类型作为成员变量时,如果没有做任何初始化则取对应类型的零值,这种情况下会导致某些业务场景的错误,例如我们的某个int变量要求必传,设置为基本类型时,假如前端没有传值,那么这个值就会得到0而不是空,这种场景就很可能导致业务上的错误:

public class Main {
    private int a;
    public static void main(String[] args) {
        System.out.println("a="+new Main().a);//a=0
    }
}

Java的三种技术架构是什么

Java有多种技术架构,但以下是其中三种常见的:

这些Java技术架构可以根据应用程序的需求和目标进行选择和使用。Java SE适用于通用的应用程序开发,Java EE适用于构建大型企业级应用,而Java ME适用于嵌入式和移动设备的开发。

JVM简介

Java虚拟机(Java Virtual Machine,JVM)是Java平台重要组成部分,它是一个在计算机上运行Java字节码的虚拟计算机,它负责解释并执行编译后的Java字节码,并将其转换为底层操作系统能够理解的机器码。

JDK和JRE分别是什么

JDK(Java Development Kit)是Java开发工具包,包含了JRE所有的东西,所以作为开发人员,只需要安装JDK即可

JRE(Java Runtime Environment)是Java运行环境,包含运行所需要的类库以及JVM。你可能认为如果仅仅要运行Java程序,安装JRE即,但是某些web程序例如需要将JSP 转换为 Java servlet就需要jdk编译了,所以保守起见,无论运行还是开发,我们都建议在操作系统上安装jdk。

什么字节码文件,字节码文件的优势是什么

首先我们了解一下从编写Java代码到Java代码被执行的过程:

JDK9的AOT技术以及为什么不全部使用 AOT 呢?

JDK9的AOT(Ahead-of-Time)编译技术使得Java字节码可直接编译为本地机器码,相比于传统JIT编译来说在运行时将字节码转为机器码,这种做法带来了两个好处:

同样的,它也带来如下几个缺点:

Java 有哪几种基本数据类型?float 和 double 的区别是?

对应的基本类型和默认0值如下:

基本类型 位数 字节 默认值
int  32    4     0
short   16    2     0
long    64    8     0L
byte    8     1     0
char    16    2   'uo000'
float   32    4    0f
double  64    8    0d
boolean  1        false

所以float为4个字节,double为8字节。

Java有那些引用类型

除了8种基本类型以外,其余类型都是引用类型即变量所存储的都是数据的引指向堆中某块内存,对应的引用类型有:

自动类型转换和强制类型转换

精度小的赋值给精度大的Java会进行自动转换,反之就需要我们进行强制转换了。

精度自小向大有两种情况,一种是字符和数字的转换,char赋值给int类型会自动转换为int。因为char占两个字节,存放都是0到 65535以内的整数,所以赋值给4个字节的int就会发生自动类型转换。

  char c = 'a';
  int num = c;

反之int转char就需要强制转换了:

 int num=1;
 char c=(char)num;

另一种情况大家就比较熟悉了,即精度小的转为精度大的发生自动类型转换,反之就是强制类型转换,如下图所示:

什么是自动装箱和自动拆箱

将基本数据类型赋值给包装类就是装箱,如下所示:

Integer i = 10;  //装箱 

这一点,我们可以通过查看字节码得以印证,可以看到底层就是通过valueOf实现装箱。

public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 5 L0
    BIPUSH 10
    //valueOf 完成类型装箱
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    ASTORE 1
   L1
    LINENUMBER 6 L1
    RETURN
   L2
    LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
    LOCALVARIABLE i Ljava/lang/Integer; L1 L2 1
    MAXSTACK = 1
    MAXLOCALS = 2
}
 Integer i = 10;
 int num = i;  //拆箱 

查看字节码,可以看到底层是通过Integer.intValue实现拆箱:

 // access flags 0x9
  public static main([Ljava/lang/String;)V
   
   L1
    LINENUMBER 6 L1
    ALOAD 1
    INVOKEVIRTUAL java/lang/Integer.intValue ()I
    ISTORE 2
   L2
    LINENUMBER 7 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE i Ljava/lang/Integer; L1 L3 1
    LOCALVARIABLE num I L2 L3 2
    MAXSTACK = 1
    MAXLOCALS = 3
}

&和&&的区别是什么

前者进行逻辑与时不会因为左边的false发生短路即表达式左右两边都会执行,而后者会发生短路,即左边得到false就不执行右边的逻辑:

具体我们可以查看下面这个例子,&运算不会发生短路,所以第一个func()结果返回false,第二个func()还是会被执行。

 public static void main(String[] args) {
        boolean b1 = func() & func();
    }

    private static boolean func() {
        System.out.println("调用了func");
        return false;
    }

从输出结果我们可以得以印证:

调用了func
调用了func

同理我们再看看&&运算,因为第一次返回了false,所以&&运算符后面的func()就不会被执行。

 public static void main(String[] args) {
        boolean b1 = func() && func();
    }

    private static boolean func() {
        System.out.println("调用了func");
        return false;
    }

输出结果如下:

调用了func

switch 是否能作用在 byte/long/String 上?

到JDK7开始byte、String都可以都可以用在switch上,但是long还是不行的。

break、continue、return的区别

最有效的计算2乘8是什么方式?

用左移运算符即 2<<3 ,这种写法在JDK的数据结构中经常可以见到,例如Arrays中的binarySearch0二分搜索,它获取中间索引时除2就是用右移运算符号。

 private static int binarySearch0(long[] a, int fromIndex, int toIndex,
                                     long key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
         //右移运算实现除2操作
            int mid = (low + high) >>> 1;
            long midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

为什么不能用浮点数表示金额?

浮点数只有8个字节,作为高精度计算的金融结算场景可能存在偏差,一般情况下针对高精度的计算,我们更推荐使用BigDecimal,因为其底层针对精度和数值进行相应的处理不会造成丢失。

BigDecimal用equals进行比较可以吗?为什么?

BigDecimal重写的equals方法比较的是两个值的精度的大小是否一致:

@Override
    public boolean equals(Object x) {
        if (!(x instanceof BigDecimal))
            return false;
        BigDecimal xDec = (BigDecimal) x;
        if (x == this)
            return true;
            //先比较精度
        if (scale != xDec.scale)
            return false;
  //再比较数值
        long s = this.intCompact;
        long xs = xDec.intCompact;
        if (s != INFLATED) {
            if (xs == INFLATED)
                xs = compactValFor(xDec.intVal);
            return xs == s;
        } else if (xs != INFLATED)
            return xs == compactValFor(this.intVal);

        return this.inflated().equals(xDec.inflated());

假设我们BigDecimal声明的分别是1.0和1.00,最终的结果就可能返回false,所以一般情况下,BigDecimal进行数值比较时我们建议使用compareTo

BigDecimal(double)和BigDecimal(String)有什么区别?

因为double只有8个字节,对于高精度的小数可能存在进度丢失问题,对应String类型因为字符串字面量的关系所以对应的小数就可以通过BigDecimal完成正确的转换。

为什么对Java中的负数取绝对值结果不一定是正数

我们都知道integer是4个字节,即取值范围是-2的31次方(-2147483648),2的31次方减一(2147483647),当-2147483648取绝对值时就会得到2147483648超过integer最大值导致越界得到负数。

Lambda表达式是如何实现的

本质上Lambda就是语法糖,编译阶段编译器会将lambda表达式进行解糖转换成对应的方法进行解析。

public static void main(String[] args) {
        List list = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
                .filter(i -> i % 2 == 0)
                .map(String::valueOf)
                .collect(Collectors.toList());

        System.out.println(list);


    }

对应的我们给出反编译后的结果,可以看到这些表达式最后都会转为Predicate.test、Function.apply等调用:

 83: aastore
        84: invokestatic  #4                  // InterfaceMethod java/util/stream/Stream.of:([Ljava/lang/Object;)Ljava/util/stream/Stream;
        87: invokedynamic #5,  0              // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
        92: invokeinterface #6,  2            // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
        97: invokedynamic #7,  0              // InvokeDynamic #1:apply:()Ljava/util/function/Function;
       102: invokeinterface #8,  2            // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
       107: invokestatic  #9                  // Method java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
       110: invokeinterface #10,  2           // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
       115: checkcast     #11                 // class java/util/List

finally中代码一定会执行吗

不会,原因如下:

你觉得Java中的枚举有什么用处?

什么是AIO、BIO和NIO

UUID是什么?可以保证全局唯一?

能,UUID即全局唯一标识,是指在一台机器上生成的id编码,由于UUID依赖MAC地址、时间戳、随机数等信息,所以UUID具有极高的唯一性,几乎是不可能重复的。

Arrays.sort是使用什么排序算法实现的

查看底层源码可知排序算法使用的是双路快排法,一种针对数组进行递归分而治之再合并的O(nlogN)级别的排序算法:

public static void sort(int[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

为什么Java中的main方法必须是public static void修饰

BigDecimal和Long哪个更适合标识金额

BigDecimal无论是使用还是进行高精度计算时都比Long类型准确。

怎么修改一个类中的private修饰的String参数的值

Stream的并行流一定比串行流更快吗

不一定,针对一些计算密集型任务。它需要时刻活跃于CPU核心才能工作,如果使用并行流以为去提升并发度,这其中上下文切换和结果聚合的开销导致的最终性能,可能还不如单线程串行运算。

小结

自此我们将java基础的核心知识进行了简单的总结,后续笔者才会针对这些题目进行进一步的迭代,希望对你有帮助。

来源:写代码的SharkChili内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯