深入了解JAVA基础(面试)

    I.常用类型与编码类问题:
        1.Java中的基本类型有什么?
            byte、short、int、long、float、double、chart、boolean这八种,这八种也挺好记,表示数字类型的有5种{整数三种[(短)short、(中)int、(长)long]、小数两种[(单精度)float、(双精度)double]},还有三种非数字类型{(表示真假)boolean、(表示字节)byte、(表示字符)char},如果实在记不住,你就记住凡是生命对象可以用小写直接声明的就是基本类型。
        2.byte、short、int、long、float、double、char以及一个string类型数据占用的字节数量?
            这是一道很基础的题,byte本身表示的就是字节,所以byte就占用一个字节;char表示一个字符占用2个字节;short表示一个短整型数据占用2个字节;int表示整型数据占用4个字节;long表示长整型数据占用8字节;float表示浮点型数据占用4个字节;double表示双精度浮点型占用8个字节;string类型的一个字符根据编码协议而定(一般没有人问),常见的编码协议有一些几种:Unicode(中文占用4字节,英文占用4字节,数字占用4字节)、UTF-8(中文占用3字节,英文占用1字节,数字占用1字节)GBK(中文占用2字节,英文占用1字节,数字占用1字节)GB2312(中文占用2字节,英文占用1字节,数字占用一字节)。[注]:byte和bit的区别?bit表示的是位,1byte=8bit,更不用担心有人问boolean类型的长度,在JDK文档中明确说了boolean的大小没有精确定义,但经过测试int类型是它的3.5倍左右,所以我们一般更倾向于占一个字节(这个就更没有人敢问了)。
        2<a>.在Java中为什么char占用两个字节?而一个字符串类型的却占4个字节?
            因为这个现象我觉的很有趣单独写成了一篇博客,见:https://www.cnblogs.com/ben-mario/p/10458318.html
        2<b>.我们都知道Java中long类型占用8个字节,float占用4个字节,为什么float表示的数字范围比long表示的范围大?
            long类型是使用二进制直接保存数据,也就是long的表示范围大小是2^64-1,float是使用类科学计数方式计数的表达方式:V=(-1)^s * M * 2^E,其中V是最终表示结果值,s(1位)表示符号位,M(23位)表示小数域范围[0,1),[1,2),E(8位)表示指数域,所以float的的表示范围:一3.403E38~3.403E38。
        2<c>.float单精度和double双精度有什么区别?
            首先内存占用不同,float是4字节,double是8字节;其次精度不同,float是单精度有效数字占8位,double是双精度有效数字占16位;然后是处理速度不同,一般来说但进度的处理速度比双精度的处理速度快。因为表示方法相同,double占用内存比float大,所以很定是表示的范围更大。
        3.String类型的创建过程是什么样的?
            直接使用String str=“test”;创建的String经过两个过程,检查String常量池,如果没有则创建一个新的String在常量池,在stack(栈)创建对象引用,引用String常量池中的常量地址。如果是使用String str = new String("test");创建String经过三个过程,检查String常量池,如果没有则创建一个新的String在String在常量池,在heak(堆)中创建一个String对象,在stack(栈)中创建一个引用对象指向堆中String对象地址。
        3<a>.在String类型中,“+”的连接是怎么实现的?“==”和String的equals方法有什么区别?
            我们都知道String类型时声明时创建的String常量,所以在String中的+将两个字符串连接,其实在底层是使用了StringBuilder的append()方法将两个String连接起来的,其最底层是byte数组扩展的,每次增加16个长度,用UFT-16字符集。在Object中其实equals方法和==是相同的,都是对比两个对象是否为同一引用,但String类中重写了equals方法,只字符串内容是否相同。

    II.不太常用的运算
        1.i++、++i(i--和--i等)的区别?
            讲真的这个问题是一个很无聊的问题,我们都知道i++是先赋值,后加1;++i是先加1,后赋值。其实i++本身是等价于i=i+1;同样的如果是++i呢?本质上也是等价于i=i+1;怎样证明呢这两个是一样的呢?我猜这个表达式你最多的是用在for循环中吧,那就使用for(int i=0;i<10;++i){System.out.println("++i:"+i);}和for(int i=0;i<10;i++){System.out.println("i++:"+i);},显然打印结果是一样的,之所以会说先赋值还是后赋值的问题是源于这样的运算:i=1;j=i++;结果是j=1;i=2;(j=i;i=i+1),i=1;j=++i;(i=i+1;j=i;),所以我们当然也可以这样理解:i++和++i的实现过程是创建临时变量temp,temp=i;i=temp+1;其中i++输出temp的值,++i输出i的值。
        2.移位运算的是什么?
            简单来说计算机中是以二进制补码存储的,以int类型为例,占4字节32位,移位有左移位和右移位两种。左移位就是将二进制数值整体向左移动n位,永远补0,在不溢出的情况下new_value=value*2^n;同样的右移就是讲二进制数值整体向右移动n位,不同的是如果是正数右移补0,负数右移补1,在不溢出的情况下new_value=value*2^n。注意移动负数位(n)时,移动方向不变,实际移动位数new_n=32+n。
        (这一块真的不怎么用得到,实际应用还需要自己先计算一遍所以没必要,理论又太偏底层计算机原理所以一般也不会问)

    III.关于类型和方法的基本问题
        1.怎样证明创建一个对象时是由类的构造器创建的?
            通常我们定一个类型是不写无参构造方法的,因为JDK会默认为没有写构造方法的类型生成一个无参的构造方法,想要证明创建对象是由构造方法创建的,我们只需要自己写出显示的构造方法并对其生命private级别,很明显我们是不能再使用new关键字创建对象的,所以创建对象是通过类构造器创建的。
        2.java中有了int(double等),为什么还要Integer(Double等)?
            java中有八种基本类型,并且八种类型都分别有自己的封装类,那么有些人会问为什么还要封装类?在面向对象编程的发展过程中,java一直都有一句“万物皆对象”的说法,就是说任何事物在java眼里都是对象,然后有人就问那基本类型是什么?我们对指导在面向对象编程中,只有对象身上才会有属性和方法,所以int没有什么方法,这个时候就有了封装类的概念,就是将基本类型包装成引用类型,这些引用类型身上是有属于各自的基本方法。虽然在存储上没有什么大的区别,但是就使用和概念上区别还是挺大的。
        3.关于类型比较时,“==”和equals()方法有什么区别?
            通常在没有重写equals()方法这两个是相同的,都是比较的对象,因为equals()方法来源于Object类中,在Object类中equals的实现就是用“==”比较的。但java的常用类型如(String、Integer等)基本是重写了equals(),主要是比较对象的值,而且一般重写equals()方法都会重写hashCode()。
        3<a>.为什么一般重写equals()方法是,我们需要写hashCode()方法?
            首先并不是重写equals()方法就一定要重写hashCode()方法。之所以通常情况下我们会重写,是因为我们可能需要在equals()方法中使用“==”比较以提高比较效率。“==”比较的是对象,而不同的对象的区分最直接的就是根据对象的hash值比较的,这就是我们需要重写hashCode()方法最直接的原因。
        

原文地址:https://www.cnblogs.com/ben-mario/p/10556896.html