• Java面试题


    1.装箱与拆箱是什么?为什么需要装箱与拆箱?

    基本类型的数据不具备“对象”的特性——不携带属性、没有方法可调用。
    Java向面向对象语言的靠近。
    在泛型中,基本类型是不可以做泛型参数的,不能用于一些集合类型。

    2.解释内存中的栈(stack)、堆(heap)和静态存储区的用法。

    通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;
    而通过new关键字和构造器创建的对象放在堆空间;
    程序中的字面量(literal)如直接书写的100、“hello”和常量都是放在静态存储区中。
    栈空间操作最快但是也很小,通常大量的对象都是放在堆空间,整个内存包括硬盘上的虚拟内存都可以被当成堆空间来使用。
    String str = new String(“hello”);
    上面的语句中str放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态存储区。

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

    Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。
    四舍五入的原理是在参数上加0.5然后进行下取整。

    4.为什么重写了equals()还需要重写hashcode()

    因为HashMap、HashTable和HashSet等是基于散列值的类,如果不重写会影响到这些类的使用。

    5.Java中只有值传递,没有引用传递。

    对,Java中传递对象是传递对象的地址。

    6.为什么不能根据返回类型来区分重载

    因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。
    例如
    float max(int a, int b);
    int max(int a, int b);
    当调用max(1, 2);时无法确定调用的是哪个,单从这一点上来说,仅返回值类型不同的重载是不应该允许的。
    再比如对下面这两个方法来说,虽然它们有同样的名字和自变量,但其实是很容易区分的: 
    void f() {} 
    int f() {} 
    若编译器可根据上下文(语境)明确判断出含义,比如在 int x=f()中,那么这样做完全没有问题。然而, 
    我们也可能调用一个方法,同时忽略返回值;我们通常把这称为“为它的副作用去调用一个方法”,因为我 
    们关心的不是返回值,而是方法调用的其他效果。所以假如我们象下面这样调用方法: 
    f(); 
    Java 怎样判断f()的具体调用方式呢?而且别人如何识别并理解代码呢?由于存在这一类的问题,所以不能根据返回值类型来区分过载的方法。
    函数的返回值只是作为函数运行之后的一个“状态”,他是保持方法的调用者与被调用者进行通信的关键。并不能作为某个方法的“标识”。

    7.描述一下JVM加载class文件的原理机制?

    JVM是通过类加载器加载class文件的,类加载器主要用于定位类定义的二进制信息,然后将这些信息解析并加载至虚拟机,转化为虚拟机内部的类型信息的数据结构。类加载器在方法区构造具有这个类的信息的数据结构后,会在堆上创建一个Class对象作为访问这个数据结构的接口。

    8.String s=new String(“xyz”);创建了几个字符串对象?

    两个对象,一个是静态存储区的"xyz",一个是用new创建在堆上的对象。

    9.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?

    可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。

    10.Java 中的final关键字有哪些用法?

    (1)修饰类:表示该类不能被继承;
    (2)修饰方法:表示方法不能被重写;
    (3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

    11.HashMap,HashTable和HashSet?

    HashMap内部创建一个长度为capacity的Entry数组,这个数组里可以存储元素的位置被称为“桶(bucket)”,每个桶只存储一个元素(也就是一个Entry),由于Entry对象可以包含一个引用变量可以指向下一个Entry,就形成了一个Entry链。
    HashSet底层是基于HashMap实现的。HashSet底层使用HashMap来保存所有元素。

    HashMap和HashTable之间的区别?

    1.继承的父类不同:HashMap(AbstractMap)、HashTable(Dictionary)
    2.对Null key和Null Value的支持不同:HashTable既不支持Null key也不支持Null Value。HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能时HashMap中没有该键,也可能该键所对应的值为null。
    3.线程安全性不同:HashTable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步。
     HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题,但是它的效率会比HashTable好很多。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。
     ConcurrentHashMap虽然也是线程安全的,但是它的效率比HashTable要高很多倍。因为ConcurrentHashMap使用的分段锁,并不对整个数据进行锁定。
    4.便利方式的内部实现不同:HashTable和HashMap都是用了iterator。而由于历史原因,Hashtable还是用了Enumeration的方式。 5.初始容量大小和每次扩充容量大小不同

    12.乐观锁和悲观锁?

    乐观锁:它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。
       在提交数据更新之间,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。 悲观锁:它可以阻止一个事物以影响其他用户的方式来修改数据。如果一个事物执行的操作读取某行数据并应用了锁,那只有当这个事物把锁释放掉,其他事物才能够执行与该锁冲突的操作。

    13.ThreadLocal(线程变量副本)

    Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。
    采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。
    ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。
    ThreadLocal在Spring中发挥着巨大的作用,在管理Request作用域中的Bean、事务管理、任务调度、AOP等模块都出现了它的身影。
    Spring中绝大部分Bean都可以声明成Singleton作用域,采用ThreadLocal进行封装,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。

    14.Lock与Synchronized的区别?

    ReentranstLock拥有Synchronized相同的并发性和内存语义,此外还多了锁投票,定义锁等候和中断锁等候。
    Synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock时通过代码实现的,要保证锁定一定会被释放,就必须将unlock()放到finally{}中。
    在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReentrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReentrantLock的性能能维持常态。

    15.String、StringBuffer与StringBuilder之间区别

    String是字符串常量,
    StringBuffer和StringBuilder是字符串变量,
    每当用string操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC掉。 StringBuffer是线程安全的,StringBuilder不是线程安全的。

    16.fail-fast机制?

    fail-fast机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
    例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。

    17.谈谈Java中的volatile

    volatile是一种轻量级的同步机制,它主要有两个特性:一是保证共享变量对所有线程的可见性;二是禁止指令重排序优化。
    同时要注意的是,volatile对于单个的共享变量的读/写具有原子性,但是像num++这种复合操作,volatile无法保证其原子性,可以使用并发包中的原子操作类,通过循环CAS的方式来保证num++操作的原子性。

    18.同步方法和同步代码块的区别

    synchronized(this)同步代码块和同步方法调用的是同一对象,即当前对象。
    同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁,
    很明显,同步方法锁的范围比较大,而同步代码块范围要小点,一般同步的范围越大,性能就越差,一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好。

    19.Java的基本数据类型有几种?

    八种。byte/short/int/long/float/double/char/boolean

    20.Java中的GC详见其他笔记
    21.Java中主要的数据结构?

    Java集合主要分为三种类型:Set(集)、List(列表)、Map(映射)。
    Set:
    1)HashSet:1.不允许重复 2.不保证顺序 3.允许最多有一个null元素
    2)TreeSet:1.可以实现排序 2.底层为树结构
    3)LinkedHashSet:1.内部使用链表维护元素的顺序(插入的次序)2.使用迭代器会按插入次序输出。
    List:
    1)ArrayList:1.代表长度可变的数组。2.对元素随机访问。3.插入与删除元素速度慢。
    2)LinkedList:1.插入删除开销不大。2.随机访问相对较慢。
    Map:
    1)HashMap:1.基于散列表的实现。2.插入和查询“键值对”的开销是固定的。
    2)LinkedHashMap:1.迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。
    3)TreeMap:1.基于红黑树数据结构的实现。
    Stack
    Queue
  • 相关阅读:
    如何获取SQL Server数据库连接字符串的某些部分
    .NET同步原语Barrier简介
    模版引擎RazorEngine简介
    如何使用SQL Server实现SignalR的横向扩展
    SignalR的客户端.NET Client介绍
    一个简单的SignalR例子
    看视频学SignalR—在微软虚拟学院学习SignalR
    看视频学Bootstrap—在微软虚拟学院学习Bootstrap
    C# 窗口与控件的相关操作
    opencv——常见的操作
  • 原文地址:https://www.cnblogs.com/yfzhou/p/9665605.html
Copyright © 2020-2023  润新知