首页 > 编程语言 >Java基础知识面试题系列四:31~40题

Java基础知识面试题系列四:31~40题

时间:2023-09-10 16:03:51浏览次数:41  
标签:面试题 Java String 31 float 40 类型 public 变量



Java基础知识面试题系列三:31~40题

  • 31.static与final结合使用表示什么意思
  • 32.使用switch时有哪些注意事项
  • 33.volatile有什么作用
  • 34.instanceof有什么作用
  • 35.strictfp有什么作用
  • 36.Java提供了哪些基本数据类型
  • 37.在Java语言中null值时什么?在内存中null是什么
  • 38.如何理解赋值语句String x = null?
  • 39.数据类型常见的一些笔试题
  • 40.什么是不可变类


31.static与final结合使用表示什么意思

  • 在Java语言中,static关键字常与final关键字结合使用,用来修饰成员变量与成员方法,有点类似于C/C++语言中的“全局变量”。
  • 对于变量,若使用static final修饰,则表示一旦赋值,就不可修改,并且通过类名可以访问。
  • 对于方法,若使用static final修饰,则表示该方法不可覆盖,并且可以通过类名直接访问。

示例:

package com.bigdata.springboot;

public class Test {

    public static int testStatic(){
        static final int i = 0;
        System.out.println(i++);
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        test.testStatic();
    }
}

上述程序的运行结果是什么?()

  • A.0
  • B.1
  • C.2
  • D.编译失败

答案:D。在Java语言中,不能在成员函数内部定义static变量。

32.使用switch时有哪些注意事项

  • switch语句用于多分支选择,在使用switch(expr)时,expr只能是一个枚举常量(内部也是由整形或字符类型实现)或一个整数表达式
  • 整数表达式 可以是基本类型int或其对应的包装类Integer,当然也包括不同的长度整型,例如short
  • 由于byte、short和char类型的值都能够被隐式地转换为int类型,因此这些类型以及它们对应的包装类型都可以作为switch的表达式。
  • long、float、double、String类型不能够隐式地转换为int类型,因此它们不能被用作switch的表达式。
  • 如果一定要使用long、float或double作为switch的参数,必须将其强制转换为int类型才可以。

示例:以下对switech中参数的使用就是非法的。

float a = 0.123;
switch(a) //错误!a不是整形或字符类型变量
{
}
  • 与switch对应的是case语句,case语句之后可以是直接的常量数值,例如1、2,也可以是一个常量计算式,例如1+2等,还可以是final型的变量,例如final int a = 0,但不能说变量或带有变量的表达式,例如i*2等。当然更不能是浮点型数,例如1.1或者1.2/2等。
  • 在Java7中,switch开始支持String类型了,switch对字符串的支持,其实是int类型值的匹配。实现原理如下:通过对case后面的String对象调用hashCode()方法,得到一个int类型的hash值,然后用这个hash值来唯一标示这个case。当匹配时,首先调用这个字符串hashCode()函数,获取一个hash值,用这个hash值来匹配所有case,如果没有匹配成功,说明不存在。如果匹配成功了,会调用字符串的String.equals()方法进行匹配。String变量不能为null,同时,switch的case子句中使用的字符串也不能为null.
  • 在使用switch时,需要注意另外一个问题:一般必须在case语句结尾添加break语句。因为一旦通过switch语句确定了入口点,就会顺序执行后面的代码,直到遇到关键字break。否则会执行满足这个case之后的其他case的语句而不管case是否匹配,直到switch结束或者遇到break为止。如果在switch语句中省略了break语句,那么匹配的case值后的所有情况(包括default情况)都会被执行。

33.volatile有什么作用

  • 在Java语言编写的程序中,有时为了提高程序的运行效率,编译器会自动对其进行优化,把经常访问的变量缓存起来,程序在读取这个变量时有可能会直接从缓存(例如寄存器)中来读取这个值,而不会去内存中读取。这样做的一个好处是提高了程序的运行效率。
  • 例如,在本线程内,当读取一个变量时,为提高存取速度,会先把变量读取到一个缓存中,当以后再取变量值时,就直接从缓存中取值,当变量值在本线程里改变时,会同时把变量的新值复制到该缓存中,以便保持一致
  • 但当遇到多线程编程时,变量的值可能因为别的线程而改变了,而该缓存的值不会相应改变。从而造成应用程序读取的值和实际的变量值不一致。
  • volatile是一个类型修饰符,被设计用来修饰被不同线程访问和修改的变量。
  • 被volatile类型定义的变量,系统每次用到它时都是直接从对应的内存当中提取,而不会利用缓存。
  • 在使用volatile修饰成员变量后,所有线程在任何时候所看到的变量的值都是相同的。

下面给出一个使用volatile的示例。

public class MyThread implements Runnable{
	private volatile Boolean flag;
	public void stop(){
		flag = false;
	}
	public void run(){
		while(flag)
		//do something
	}
}
  • 以上代码示例是用来停止线程最常用的一种方法,如果boolean类型的变量flag没有被声明为volatile,当这个线程的run方法在判断flag值时,使用的有可能是缓存中的值,此时就不能及时地获取其他线程对flag所做的操作,因此会导致线程不能及时地停止。
  • 需要注意的是,由于volatile不能保证操作的原子性,因此,一般情况下volatile不能代替sychronized。
  • 使用volatile会阻止编译器对代码的优化,因此会降低程序的执行效率。
  • 除非迫不得以,否则,能不使用volatile就尽量不要使用volatile

34.instanceof有什么作用

  • instanceof是Java语言中的一个二元运算符,它的作用是判断一个引用类型的变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例
  • 即它左边的对象是否是它右边的类的实例该运算符返回boolean类型的数据。
  • 常见的用法为:result=object instanceof class,如果object是class的一个实例,那么instanceof运算符返回true。如果object不是class的一个实例,或者object是null,那么instanceof运算符返回false。

以如下程序为例:

import java.lang.String;

public class InstanceOf {
    public static void main(String[] args) {
        String s = "Hello";
        int[] a = {1,2};
        if(s instanceof String)
            System.out.println("true");
        if(s instanceof Object)
            System.out.println("true");
        if(a instanceof int[])
            System.out.println("true");
    }
}

程序结果为:
true
true
true

35.strictfp有什么作用

  • 关键字strictfp是strict float point的缩写,指的是精确浮点,用来确保浮点数运算的准确性。
  • JVM在执行浮点数运算时,如果没有指定stricfp关键字,此时计算结果可能会不精确,而且计算结果在不同平台或厂商的虚拟机上会有不同的结果,导致意想不到的错误。
  • 一旦使用了strictfp来声明一个类、接口或者方法,那么在所声明的范围内,Java编译器以及运行环境会完全依照IEEE二进制浮点数算术标准来执行,在这个关键字声明的范围内所有浮点数的计算都是精确的。
  • 需要注意的是,当一个类被stricfp修饰时,所有方法都会自动被strictfp修饰。
  • strictfp可以保证浮点数运算的准确性,而且在不同的硬件平台上会有一致的运行结果。

下次给出了strictfp修饰类的使用方法:

public strictfp class TestStrictfp {
    public static void testStrictfp() {
        float f = 0.12365f;
        double d = 0.03496421d;
        double sum = f+d;
        System.out.println(sum);
    }

    public static void main(String[] args) {
        testStrictfp();
    }
}

程序运行结果为:
0.15861420949932098

36.Java提供了哪些基本数据类型

Java语言一共提供了8种原始的数据类型:

  • byte
  • short
  • int
  • long
  • float
  • double
  • char
  • boolean
  • 这些数据类型不是对象,而是Java语言中不同于类的特殊类型
  • 这些基本类型的数据变量在声明之后就会立刻在栈上被分配内存空间
  • 除了这8种基本的数据类型外,其他类型都是引用类型(例如类、接口、数组等)
  • 引用类型类似于C++中的引用或指针的概念
  • 它以特殊的方式指向对象实体,这类变量在声明时不会被分配内存空间,只是存储了一个内存地址而已。

不同数据类型对比:

数据类型

包装类

int

Integer

short

Short

long

Long

byte

Byte

float

Float

double

Double

char

Character

boolean

Boolean

以上这些基本类型可以分为如下4种类型:

  • int长度数据类型:byte(8bit)、short(16bit)、int(32bit)、long(64bit)
  • float长度数据类型:单精度(32bit float)、双精度(64 bit double)
  • boolean类型变量的取值:true、false。对于boolean占用空间的大小,从理论上讲,只需要1bit就够了,但在设计的时候为了考虑字节对齐等因素,一般会考虑使其占用一个字节。由于Java规范没有明确的规定,因此,不同的JVM可能会有不同的实现。
  • char数据类型:unicode(16bit)

Java语言还提供了对这些原始数据类型的封装类(字符类型Character、布尔类型Boolean、数值类型Byte、Short、Integer、Long、Float、Double)。

  • Java中的数值类型都是有符号的,不存在无符号的数,取值范围也是固定的,不会随着硬件环境或者操作系统的改变而改变。
  • 除了8种基本数据类型外,Java语言中还存在着一种基本类型void,也有对应的封装类java.lang.void,只是无法直接对它进行操作而已。

封装类型和原始类型的区别:

  • 原始数据类型在传递参数时都是按值传递,而封装类型是按引用传递的
  • 当封装类型和原始类型用作某个类的实例数据时,它们所指定的默认值不同。
  • 对象引用实例变量的默认值为null,而原始类型实例变量的默认值与它们的类型有关。

示例如下:

public class Test {
    String s;
    int i;
    float f;

    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.s == null);
        System.out.println(t.i);
        System.out.println(t.f);
    }
}

程序运行结果为:
true
0
0.0

需要注意的是:

  • Java语言中,默认声明的小数是double类型的,因此在对float类型的变量进行初始化时需要进行类型转换。
  • float类型的变量有两种初始化方法:float f=1.0f 或 float f = (float) 1.0
  • 在Java语言中,直接写的整形数字是int类型的,如果在给数据类型为long的变量直接赋值时,int类型的值无法表示一个非常大的数字,因此,在赋值时可以通过如下的方法来赋值:long l = 26012402244L

37.在Java语言中null值时什么?在内存中null是什么

  • null不是一个合法的Object实例,所以编译器并没有为其分配内存,仅仅用于表明该引用目前没有指向任何对象。
  • 与C语言类似,null是将引用变量的值全部置为0

38.如何理解赋值语句String x = null?

  • 在Java语言中,变量被分为两大类型:原始值与引用值。
  • 声明为原始类型的变量,其存储的是实际的值。
  • 声明为引用类型的变量,存储的是实际对象的地址(指针、引用)
  • 对于赋值语句String x = null,定义了一个变量“x”,x中存放的是String引用,此处为null

39.数据类型常见的一些笔试题

(1)下列表达式中,正确的是()

  • A.byte b = 128;
  • B.boolean flag = null;
  • C.float f = 0.9239
  • D.long a = 2147483648L;
    答案:D。A中byte能表示的取值范围为[-128,127],因此不能表示128。B中boolean的取值只能是true或false,不能为null。C中0.923为double类型,需要进行数据类型转换。

(2) String是最基本的数据类型么?
答案:不是。基本数据类型包括byte、int、char、long、float、double、boolean和short

(3) int和Integer有什么区别?
答案:

  • Java语言提供两种不同的类型,即引用类型和原始类型(或内置类型)。
  • int是Java语言的原始数据类型,Integer是Java语言为int提供的封装类。
  • Java为每个原始类型提供了封装类。
  • 引用类型与原始类型的行为完全不同,并且它们具有不同的语义。而且,引用类型与原始类型具有不同的特征和用法。

(4) 赋值语句float f = 3.4是否正确?

答案:不正确。

  • 数据3.4默认情况下是double类型,即双精度浮点数,将double类型数值赋值给float类型的变量,会造成精度损失,因此需要对其进行强制类型转换
  • 即将3.4转换成float类型或者将3.4强制写成float类型,所以float f = (float)3.4 或者float f = 3.4F写法都是可以的

40.什么是不可变类

  • 不可变类是指当创建了这个类的实例后,就不允许修改它的值了,
  • 也就是说一个对象一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了。
  • 类似于常量,即只允许别的程序读,不允许别的程序进行修改。
  • 在Java类库中,所有基本类型的包装类都是不可变,例如Integer、Float等。
  • String也是不可变类。

既然String是不可变类,为什么还可以写出如下代码来修改String类型的值?

public class Test {
    public static void main(String[] args) {
        String s = "hello";
        s += " world";
        System.out.println(s);
    }
}

程序运行结果为:
Hello world

  • 表明上看,好像是修改String类型对象s的值。其实不是,String s = "Hello"语句声明了一个可以指向String类型对象的引用,这个引用名字为s,它指向了一个字符串常量 “Hello”。
  • s+=" world"并没有改变s所指向的对象(由于“Hello”是String类型的对象,而String又是不可变量),这句代码运行后,s指向了另外一个String类型的对象,该对象的内容为“Hello world”。
  • 原来的那个字符串串常量“Hello”。还存在于内存中,并没有被改变。

介绍完不可变类的基本概念后,下面主要介绍如何创建一个不可变类。通常来讲,要创建一个不可变类需要遵循下面4条基本原则:

  • 类中所有成员变量被private所修饰
  • 类中没有写或者修改成员变量的方法,例如setxxx,只提供构造函数,一次生效,永不可改变。
  • 确保类中所有方法不会被子类覆盖,可以通过把类定义为final或者把类中的方法定义为final来达到这个目的。
  • 如果一个类成员是不是不可变量,那么在成员初始化或者使用get方法获取该成员变量时,需要通过clone方法来确保类的不可变性。
  • 如果有必要,可使用覆盖Object类的equals()方法和hashCode()方法。在equals()方法中,根据对象的属性值来比较两个对象是否相等,并且保证用equals()方法判断为相等的两个对象的hashCode()方法的返回值也相等,这可以保证这些对象能被正确地放到HashMap或HashSet集合中。

需要注意的事项:

  • 由于类的不可变性,在创建对象时就需要初始化所有成员变量,因此最好提供一个带参数的构造函数来初始化这些成员变量。

Java语言中之所以有很多不可变类,主要是不可变类具有使用简单、线程安全、节省内存等优点。
有利就有弊,不可变类自然也有其缺点,例如,不可变类的对象会因为值的不同而产生新的对象,从而导致无法预料的问题。所以,切不可滥用这种模式。

下面通过给出一个错误实现方法与一个正确的实现方法来说明在实现这种类时需要特别注意的问题。

首先给出一个错误的实现方法:

import java.util.Date;

class ImmutableClass{
    private Date d;
    public ImmutableClass(Date d){
        this.d = d;
    }

    public void printState() {
        System.out.println(d);
    }
}


public class TestImmutable {
    public static void main(String[] args) {
        Date d = new Date();
        ImmutableClass immuC = new ImmutableClass(d);
        immuC.printState();
        d.setMonth(5);
        immuC.printState();

    }
}

程序运行结果如下所示:
Thu Aug 12 09:48:51 CST 2021
Sat Jun 12 09:48:51 CST 2021

  • 由于Date对象的状态是可以被改变的,而ImmutableClass保存了Date类型对象的引用,当被引用的对象的状态改变时会导致ImmutableClass对象状态的改变。

正确的实现方法如下所示:

import java.util.Date;

class ImmutableClass{
    private Date d;
    public ImmutableClass(Date d){
        this.d = (Date)d.clone();
    }

    public void printState() {
        System.out.println(d);
    }
}


public class TestImmutable {
    public static void main(String[] args) {
        Date d = new Date();
        ImmutableClass immuC = new ImmutableClass(d);
        immuC.printState();
        d.setMonth(5);
        immuC.printState();

    }
}

程序的运行结果如下所示:
Thu Aug 12 09:51:55 CST 2021
Thu Aug 12 09:51:55 CST 2021


标签:面试题,Java,String,31,float,40,类型,public,变量
From: https://blog.51cto.com/u_12080573/7426475

相关文章

  • Java基础知识面试题系列七:61~70题
    Java基础知识面试题系列七:61~70题61、JavaIO流的实现机制是什么62、管理文件和目录的类是什么63、如何列出某个目录下的所有目录和文件64、JavaSocket是什么65.用Socket实现客户端和服务器端的通信,要求客户发送数据后能够回显相同的数据66.JavaNIO是什么67.什么是Java序列化68.......
  • Java基础知识面试题系列六:51~60题
    Java基础知识面试题系列六:51~60题51."=="、equals和hashCode有什么区别52.String、StringBuffer、StringBuilder和StringTokenizer有什么区别53.Java中数组是不是对象54.数组的初始化方式有哪几种55.length属性与length()方法有什么区别56.异常处理的原理是什么57.运行时异常和普通......
  • Java基础知识面试题系列八:81~90题
    Java基础知识面试题系列七:81~90题81.JavaCollections框架是什么82.什么是迭代器83.Iterator与ListIterator有什么区别84.ArrayList、Vector和LinkedList有什么区别85.ArrayList、Vector和LinkedList容器使用场景选择86.HashMap、Hashtable、TreeMap和WeakHashMap有哪些区别87.Hash......
  • [ABC319G] Counting Shortest Paths
    [ABC319G]CountingShortestPathsAtcoder:[ABC319G]CountingShortestPaths洛谷:[ABC319G]CountingShortestPathsProblem经典问题:求补图的最短路,边权均为\(1\),并顺带求出\(1\ton\)最短路的数量。\(n\le2\times10^5\)。Solution每次从队列中把最早遍历到的节点......
  • CF431B 题解
    思路分析答题思路一道纯暴力题!因为我们发现数据最大是\(5\),而枚举全排列的时间复杂度为\(\mathcalO(n!)\),对于这种极小的数据范围是丝毫不用顾虑的,因为我们只需要执行\(120\)次。如何快速求出一个数组的全排列?我们可以使用dfs,一层一层获取这个数组的全排列。但是STL......
  • JVM调优篇:探索Java性能优化的必备种子面试题
    JVM内存模型首先面试官会询问你在进行JVM调优之前,是否了解JVM内存模型的基础知识。这是一个重要的入门问题。JVM内存模型主要包括程序计数器、堆、本地方法栈、Java栈和方法区(1.7之后更改为元空间,并直接使用系统内存)。正常堆内存又分为年轻代和老年代。在Java虚拟机中,年轻代用于存......
  • 代码随想录算法训练营第四天| 24. 两两交换链表中的节点, 19.删除链表的倒数第N个结点
    24.两两交换链表中的节点mydemo(超时)/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val(0),next(nullptr){}*ListNode(intx):val(x),next(nullptr){}*ListNode(intx,Lis......
  • QT7331 14bit 2 通道3/2.6/2GS/s ADC + 16bit 2 通道12.6GS/s DAC FMC AD/DA 子卡
    概要QT7331是一款高分辨率、高采样率的ADC+DACFMC子板。它同时支持2路14位3.0/2.6/2.0GS/s的A/D通道输入和2路16位12.6GS/s的D/A通道输出,全功率模拟-3dB输入带宽可达9GHz。QT7331A为3GSPS采样率,QT7331B为2.6GSPS采样率,QT7331C为2GSPS采样率。本板卡支持触发输入或者输出;内参考、......
  • 9.9续8.31java添加图片
    JLabel管理区域:图片,文字API帮助文档:方法的用法宽高(单位:像素),边框 将图片文件夹粘贴到idea当前模块(最大)下 Imagelcon图片对象:ImageIcon对象名=newImageIcon(图片地址);JLabel对象名=newJLabel(图片对象名);  //管理容器的创建add(管理对象名);  //位置确定后再调用......
  • 掌握这些面试题和技巧,Android程序员轻松提高拿到offer的概率
    前言在竞争激烈的IT行业,程序员面试成为了每个开发者必须经历的一道关卡。无论是应聘初级岗位还是高级职位,面试都扮演着决定命运的重要角色。然而,对于很多程序员来说,面试过程充满了不确定性和挑战。下面将在面试中,总结出来的一些建议和策略分享给大家。一、了解面试流程与目标:在准备......