面试准备之Java 基础(应用篇)

简介: 面试准备之Java 基础(应用篇)

1、Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?


Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。


Math.round 方法返回的是一个最接近参数的 long 值(例如:Math.round(11.6) = 12;Math.round(-11.6) = -12;Math.round(-0.1) = 0;Math.round(0.1) = 0) 。

如果出现向上向下距离一样的数值,比如题目中的11.5 ,取较大的值。比如:


  • Math.round(11.5) ,首先与 11.5最接近的有两个整数 11 和 12,取较大的那结果就是12;
  • Math.round(-11.5),首先与 -11.5最接近的有两个整数 -11 和 -12,取较大的那结果就是-11;
  • Math.round(0.5),首先与 0.5最接近的有两个整数 0 和 1,取较大的那结果就是1;
  • Math.round(-0.5),首先与 -0.5最接近的有两个整数 -1 和 0,取较大的那结果就是0;


1.如果参数为 NaN(无穷与非数值),那么结果为 0。 2.如果参数为负无穷大或任何小于等于 Long.MIN_VALUE 的值,那么结果等于Long.MIN_VALUE 的值。 3.如果参数为正无穷大或任何大于等于 Long.MAX_VALUE 的值,那么结果等于Long.MAX_VALUE 的值。


2、Math.ceil和Math.floor的使用


Math.ceil(-0.5)等于 -0.0,Math.floor(-0.5)等于-1.0。

ceil:天花板数,向上取整;floor:地板数,向下取整。取整结果符号不变,类型不变。


3、String str="i"与 String str=new String("i")一样吗?


不一样,运行时涉及到的对象数目不同,前者涉及到一个对象,即字面量“i”在堆中创建的对象,并将其引用驻留在字符串常量池中;后者涉及到两个对象,多了一个通过 new String("i")在堆中创建并初始化的、内容与"i"相同的对象。


关于 String 类的相关知识,推荐阅读Java 基础:String 类源码分析Java 基础:String——常量池与 intern


4、Java中的String有没有长度限制?


在 String 源码分析中,关于其构造方法的实现比较多,其中有几个是支持用户传入 length 来执行长度的:


public String(byte bytes[], int offset, int length) 
复制代码


可以看到,这里面的参数 length 是使用 int 类型定义的,那么也就是说,String 定义的时候,最大支持的长度就是 int 的最大范围值。


根据 Integer 类的定义,java.lang.Integer#MAX_VALUE的最大值是2^31 – 1;


那么,我们是不是就可以认为 String 能支持的最大长度就是这个值了呢?


其实并不是,这个值只是在运行期,我们构造 String 的时候可以支持的一个最大长度,而实际上,在运行期,定义字符串的时候也是有长度限制的。


如以下代码:


String s = "11111...1111";//其中有10万个字符"1"
复制代码


当我们使用如上形式定义一个字符串的时候,当我们执行 javac 编译时,是会抛出异常的,提示如下:


错误: 常量字符串过长
复制代码


那么,明明 String 的构造函数指定的长度是可以支持2147483647(2^31 – 1)的,为什么像以上形式定义的时候无法编译呢?


常量池限制


原因在于: 形如String s = "xxx";定义String的时候,xxx被我们称之为字面量,这种字面量在编译之后会以常量的形式进入到 Class 文件常量池。 要进入常量池,就要遵守常量池的约束条件。


Class 文件常量池的格式规定:其字符串常量的长度不能超过65535( 2^16 – 1 ), 当参数类型为 String,并且长度大于等于 65535 的时候,就会导致编译失败。


运行期限制


首先我们查看以下代码:


String s = "";
for (int i = 0; i <100000 ; i++) {
    s+="i";
}
复制代码


在运行期,长度不能超过 Int 的范围,否则会抛异常。


推荐阅读:String长度限制


5、用最有效率的方法计算2乘以8?


2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。


6、数组有没有length()方法?String有没有length()方法?


数组没有 length()方法,有 length 的属性。 String 有 length()方法。在 JavaScript 中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。


7、在Java中,如何跳出当前的多重嵌套循环?


在最外层循环前加一个标记如 A,然后用 break A;可以跳出多重循环。(Java 中支持带标签的 break 和 continue  语句,作用有点类似于 C 和 C++中的 goto 语句,但是就像要避免使用 goto 一样,应该避免使用带标签的 break 和 continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用)


8、两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对?



不对,如果两个对象x和y满足 x.equals(y) == true,它们的哈希码(hash code)应当相同。


(1)如果两个对象相同(equals方法返回true),那么它们的 hashCode 值一定要相同;

(2) 如果两个对象的 hashCode 相同,它们并不一定相同。


9、两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?


不对,两个对象的 hashCode()相同,equals()不一定 true。


String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", 
                     str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
//结果
str1:1179395 | str2:1179395
false
复制代码


代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。


10、float f=3.4;是否正确?


不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换 float f =(float)3.4; 或者写成 float f =3.4F;。


11、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?


对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int  型,需要强制转换类型才能赋值给 short 型。而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short)(s1 + 1);其中有隐含的强制类型转换。


byte b1 = 1, b2 = 2, b3, b4;
final byte b5 = 5, b6 = 6;
b4=b5+b6; //常量在编译阶段直接赋值,注意byte的取值范围,不要大于127
b3=b1+b2; //编译报错
复制代码


12、判断语句的案例


boolean f1 = false;
if(f1 = true){
    System.out.println("true"); //输出true
}else {
    System.out.println("false");
}
int a = -1;
if(a = 1){  //编译报错,注意与js代码的区别,数字
    System.out.println(a);
}else{
    System.out.println(a);
}
复制代码


13、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?


在 Java 5以前,switch(expr)中,expr 只能是 byte、short、char、int;从 Java 5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型;从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。


14、枚举类型的使用


枚举类有多少个实例,就会调用多少次构造方法,枚举类构造方法只能加 private 修饰符(或不加),因为枚举类本身已经是构造好的,不允许再被外部构造。


查看如下一个案例:


public class Test2{
    public static void main(String[] args) {
        System.out.println(User.one);
    }
}
enum User{
    one,two,three;
    private User(){
        System.out.println("执行构造方法");
    }
}
复制代码


执行结果为:


执行构造方法
执行构造方法
执行构造方法
one
复制代码


关于枚举的更多内容推荐阅读:Java 枚举(enum) 详解7种常见的用法


15、正确使用 equals 方法


Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。


举个例子:


// 不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常
String str = null;
if (str.equals("hresh")) {
  ...
} else {
  ..
}
复制代码


运行上面的程序会抛出空指针异常,但是我们把第二行的条件判断语句改为下面这样的话,就不会抛出空指针异常,else 语句块得到执行。:


"hresh".equals(str);// false 
复制代码


推荐使用 java.util.Objects#equals(JDK7 引入的工具类)。


Objects.equals(null,"hresh");// false
复制代码


该方法源码如下:


public static boolean equals(Object a, Object b) {
        // 可以避免空指针异常。如果a==null的话此时a.equals(b)就不会得到执行,避免出现空指针异常。
        return (a == b) || (a != null && a.equals(b));
    }
复制代码


注意

  • 每种原始类型都有默认值一样,如 int 默认值为 0,boolean 的默认值为 false,null 是任何引用类型的默认值,不严格的说是所有 Object 类型的默认值。


  • 可以使用 == 或者 != 操作来比较 null 值,但是不能使用其他算法或者逻辑操作。在 Java 中 null == null 将返回 true。


  • 不能使用一个值为 null 的引用类型变量来调用非静态方法,否则会抛出异常

推荐阅读:Java中equals方法造成空指针异常的原因及解决方案


16、关于浮点数运算丢失精度问题(BigDecimal)


问题案例:


float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999964
System.out.println(a == b);// false
复制代码
public static void main(String args[]){
    System.out.println(0.05+0.01);
    System.out.println(1.0-0.42);
    System.out.println(4.015*100);
    System.out.println("BigDecimal:"+new BigDecimal(Double.toString(4.015)).multiply(new BigDecimal(Double.toString(100))));
    System.out.println(123.3/100);
}
//输出结果
0.060000000000000005
0.5800000000000001
401.49999999999994
BigDecimal:401.5000
1.2329999999999999
复制代码


使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作。在 BigDecimal 类中有很多个构造方法,关于浮点型数据作为参数的构造方法只有两个:


public BigDecimal(double var1)//默认舍入模式为MathContext.UNLIMITED具有无限精度算法
public BigDecimal(double var1, MathContext var3)//自定义舍入模式
复制代码


在实际应用中会发现,public BigDecimal(double val) 损失了double 参数的精度,如下例所示:


double d = 301353.05;
BigDecimal decimal = new BigDecimal(d);
System.out.println(decimal);
//输出结果为:301353.0499999999883584678173065185546875
复制代码


为避免该情况的出现,最简单有效的方法是使用 BigDecimal 的以 String 为参数的构造函数:public BigDecimal(String val)  来替代。


还有关于四舍五入的情况,也会出现问题。


double a1 = 4.015;
double a2 = Math.round(a1*100)/100.0;
System.out.println(a2);//4.01
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(Double.valueOf(df.format(a1)));//4.01
复制代码


在商业计算中,对数据要求特别严格的情况下,比如有关金钱数据,最好使用 BigDecimal。下方是针对浮点型数据构建的加减乘除和四舍五入的工具类。


/**
 * @author hresh
 * @description https://juejin.cn/user/2664871918047063
 */
public class Arith{
    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 10;
    //这个类不能实例化
    private Arith(){
    }
    /**
     * 提供精确的加法运算。
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }
    /**
     * 提供精确的减法运算。
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double sub(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    } 
    /**
     * 提供精确的乘法运算。
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double mul(double v1,double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }
    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
     * 小数点以后10位,以后的数字四舍五入。
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */
    public static double div(double v1,double v2){
        return div(v1,v2,DEF_DIV_SCALE);
    }
    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入。
     * @param v1 被除数
     * @param v2 除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1,double v2,int scale){
        if(scale<0){
            throw new IllegalArgumentException(
                "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    /**
     * 提供精确的小数位四舍五入处理。
     * @param v 需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v,int scale){
        if(scale<0){
            throw new IllegalArgumentException(
                "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}
复制代码


通过将 double 型数据转换为 BigDecimal 再进行计算,可以保证数据的准确性。


总结


BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。


BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念


推荐阅读:



目录
相关文章
|
24天前
|
存储 数据采集 搜索推荐
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
本篇文章探讨了 Java 大数据在智慧文旅景区中的创新应用,重点分析了如何通过数据采集、情感分析与可视化等技术,挖掘游客情感需求,进而优化景区服务。文章结合实际案例,展示了 Java 在数据处理与智能推荐等方面的强大能力,为文旅行业的智慧化升级提供了可行路径。
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
|
24天前
|
机器学习/深度学习 数据采集 数据可视化
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用(216)
本文探讨Java大数据可视化在城市空气质量监测与污染溯源中的创新应用,结合多源数据采集、实时分析与GIS技术,助力环保决策,提升城市空气质量管理水平。
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用(216)
|
24天前
|
存储 监控 数据可视化
Java 大视界 -- 基于 Java 的大数据可视化在企业生产运营监控与决策支持中的应用(228)
本文探讨了基于 Java 的大数据可视化技术在企业生产运营监控与决策支持中的关键应用。面对数据爆炸、信息孤岛和实时性不足等挑战,Java 通过高效数据采集、清洗与可视化引擎,助力企业构建实时监控与智能决策系统,显著提升运营效率与竞争力。
|
24天前
|
Java 大数据 数据处理
Java 大视界 -- 基于 Java 的大数据实时数据处理在工业互联网设备协同制造中的应用与挑战(222)
本文探讨了基于 Java 的大数据实时数据处理在工业互联网设备协同制造中的应用与挑战。文章分析了传统制造模式的局限性,介绍了工业互联网带来的机遇,并结合实际案例展示了 Java 在多源数据采集、实时处理及设备协同优化中的关键技术应用。同时,也深入讨论了数据安全、技术架构等挑战及应对策略。
|
24天前
|
数据采集 搜索推荐 Java
Java 大视界 -- Java 大数据在智能教育虚拟学习环境构建与用户体验优化中的应用(221)
本文探讨 Java 大数据在智能教育虚拟学习环境中的应用,涵盖多源数据采集、个性化推荐、实时互动优化等核心技术,结合实际案例分析其在提升学习体验与教学质量中的成效,并展望未来发展方向与技术挑战。
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
Java 大视界 -- Java 大数据机器学习模型在自然语言生成中的可控性研究与应用(229)
本文深入探讨Java大数据与机器学习在自然语言生成(NLG)中的可控性研究,分析当前生成模型面临的“失控”挑战,如数据噪声、标注偏差及黑盒模型信任问题,提出Java技术在数据清洗、异构框架融合与生态工具链中的关键作用。通过条件注入、强化学习与模型融合等策略,实现文本生成的精准控制,并结合网易新闻与蚂蚁集团的实战案例,展示Java在提升生成效率与合规性方面的卓越能力,为金融、法律等强监管领域提供技术参考。
|
24天前
|
存储 人工智能 算法
Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用(227)
本文探讨 Java 大数据在智能医疗影像压缩与传输中的关键技术应用,分析其如何解决医疗影像数据存储、传输与压缩三大难题,并结合实际案例展示技术落地效果。
|
24天前
|
机器学习/深度学习 安全 Java
Java 大视界 -- Java 大数据在智能金融反洗钱监测与交易异常分析中的应用(224)
本文探讨 Java 大数据在智能金融反洗钱监测与交易异常分析中的应用,介绍其在数据处理、机器学习建模、实战案例及安全隐私等方面的技术方案与挑战,展现 Java 在金融风控中的强大能力。
|
24天前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。
|
24天前
|
机器学习/深度学习 搜索推荐 数据可视化
Java 大视界 -- Java 大数据机器学习模型在电商用户流失预测与留存策略制定中的应用(217)
本文探讨 Java 大数据与机器学习在电商用户流失预测与留存策略中的应用。通过构建高精度预测模型与动态分层策略,助力企业提前识别流失用户、精准触达,实现用户留存率与商业价值双提升,为电商应对用户流失提供技术新思路。