【面试】Java基础篇(二)

0、问题大纲

一、Java 基础

1.2 方法操作

1== 和 Equals的区别,如果重写了Equals()不重写HashCode()会发生什么?

2、Java有个最基本的类Object,这个类默认包含哪几个方法?

3、对比Vector、ArrayList、LinkedList有何区别?【第8讲】(*4- 追问1:是不是线程安全的?
 - 追问2:各自应用场景是什么?

4、对比Hashtable、HashMap、TreeMap有什么不同?【第9讲】(*3)
 - 更多:……
// 接HashMap之追问系列
	1、为什么是 0.75 这个值呢?
	
	2、什么办法来解决因链表过长导致查询时间复杂度高的问题呢?
	
	3、影响 HashMap 性能的因素?
	
	4、HashMap的哈希函数怎么设计的?
	 - 追问1:初始容量为什么设置为 2 的整数次幂?【(n - 1) & hash 】
	 - 追问2:如果没使用 hash() 方法计算 hashCode,直接使用对象的 hashCode 值,会出现什么问题呢?
	 - 追问3:为什么获取下标时用按位与 &,而不是取模 %5、JDK1.8后对HashMap的改进(*3- 追问1:为什么要做这几点优化?
	 - 追问21.8 中的 HashMap 是否线程安全?
	 - 追问3:什么时机执行 resize()- 追问4resize() 如何实现的?
	
	6、HashMap get和put源码,
	
	7、HashMap 的 key 需要满足什么条件?
	 - 追问1:HashMap 允许 key/value 为 null, 但最多只有一个。 为什么?
	 - 追问2:如果重写了equals(),不重写hashCode()会发生什么?
	
	8、你平常怎么解决这个线程不安全的问题?
	
	9、那你知道ConcurrentHashMap的分段锁的实现原理吗?
5、HashSet底层实现?
 - 追问1:线程安全吗?

6、Java提供了哪些IO方式(*2)? NIO如何实现多路复用?【第11讲】

7、Java有几种文件拷贝方式?哪一种最高效?【第12讲】

8、写正则表达式进行手机号匹配(*2)。

一、Java 基础

1、== 和 Equals的区别?

== :基本数据类型:比较值;引用数据类型:比较对象的(堆)内存地址内存。

equals :默认是引用比较,很多类(String、Integer)重写 equals,变成了值比较。

// 举例:
public class StringDemo {
    
    
    public static void main(String args[]) {
    
    
        String str1 = "Hello";
        String str2 = new String("Hello");  // 开辟新的堆内存
        String str3 = str2; // 引用传递
        System.out.println(str1 == str2); // false
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str2.equals(str3)); // true
    }
}

2、Java有个最基本的类Object,这个类默认包含哪几个方法?

函数名 功能
registerNatives() 对本地方法进行注册
getClass() 返回一个对象的运行时类
hashCode() 返回该对象的哈希值
equals() 指示某个其他对象是否与此对象相等
clone() 创建并返回此对象的一个副本
toString() 返回该对象的字符串表示
notify() 唤醒此对象监视器上等待的单个线程
notifyAll() 唤醒此对象监视器上等待的所有线程
wait(long) 导致当前线程等待调用此对象的notify()或notifyAll()
wait(long,int) 导致当前线程等待,直到其他线程调用此对象的notify()或notifyAll(),或其他某个线程中断当前线程,或已经超过某个实际时间量
wait() 导致当前线程等待,直到其他线程调用此对象的notify()或notifyAll()
finalize() 当垃圾回收确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
Object() 默认构造方法

3、对比Vector、ArrayList、LinkedList有何区别?【第8讲】(*2):存储,线程,扩容

对象 存储 线程 扩容
Vector 动态数组 Y 100%
ArrayList 动态数组 N 50%
LinkedList 双向链表 N -
追问1:各自应用场景是什么?

Vector 和 ArrayList 以数组形式顺序存储,所以非常适合随机访问
LinkedList 进行插入、删除很高效,但随机访问比动态数组慢。

4、对比Hashtable、HashMap、TreeMap有什么不同?【第9讲】(*6)

Hashtable同步的哈希表实现,不支持 null 键和值。同步让开销更大,很少使用。

HashMap不同步的哈希表实现,支持 null 键和值等。put、get 操作通常可达到常数时间性能,是绝大部分键值对存取首选。

TreeMap 是基于红黑树的一种提供顺序访问Mapget、put、remove 类操作时间复杂度是 O(logn),具体顺序由 指定Comparator 或 键的自然顺序 来决定。

补充:
1、相同:都是 Map 实现,是以键值对形式存储和操作数据的容器类型。
2、容器:存储元素的单元。这样来看,数据类型都是容器。
3、线程同步:多线程操作一个资源导致资源不一致,这需要协调资源的调度,即线程同步。
4、线程安全:多线程访问类X时,X都表现正确行为,则X是线程安全。 线程安全类封装了同步机制。

追问系列:

1、为什么是 0.75 这个值呢?

2、什么办法来解决因链表过长导致查询时间复杂度高的问题呢?

3、影响 HashMap 性能的因素?

4、HashMap的哈希函数怎么设计的?
 - 追问1:初始容量为什么设置为 2 的整数次幂?【(n - 1) & hash 】
 - 追问2:如果没使用 hash() 方法计算 hashCode,直接使用对象的 hashCode 值,会出现什么问题呢?
 - 追问3:为什么获取下标时用按位与 &,而不是取模 %5、JDK1.8后对HashMap的改进(*3- 追问1:为什么要做这几点优化?
 - 追问21.8 中的 HashMap 是否线程安全?
 - 追问3:什么时机执行 resize()- 追问4resize() 如何实现的?

6、HashMap get和put源码,

7、HashMap 的 key 需要满足什么条件?
 - 追问1:HashMap 允许 key/value 为 null, 但最多只有一个。 为什么?
 - 追问2:如果重写了equals(),不重写hashCode()会发生什么?

8、你平常怎么解决这个线程不安全的问题?

9、那你知道ConcurrentHashMap的分段锁的实现原理吗?

回答详解见:【疑惑整理】【Java】深入浅出HashMap+面试整理

5、HashSet底层实现?

在HashMap上包了一层,默认存储一个Object的静态常量,取时候也是只返回key。其中add方法调用HashMap的put()方法实现。

if key is existed, then 是旧值,失败;
if (map.put()==null), then 添加元素作为map.key

追问1:线程安全吗?

不安全,同HashMap。

6、Java提供了哪些IO方式(*2)? NIO如何实现多路复用?【第11讲】

Java IO 方式有很多种,基于不同的 IO 抽象模型和交互方式,可以进行简单区分。

首先,传统的 java.io 包,它基于流模型实现,提供了我们最熟知的一些 IO 功能,比如 File 抽象、输入输出流等。交互方式是同步、阻塞的方式,也就是说,在读取输入流或者写入输出流时,在读、写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线性顺序。

java.io 包的好处是代码比较简单、直观,缺点则是 IO 效率和扩展性存在局限性,容易成为应用性能的瓶颈。

很多时候,人们也把 java.net 下面提供的部分网络 API,比如 Socket、ServerSocket、HttpURLConnection 也归类到同步阻塞 IO 类库,因为网络通信同样是 IO 行为。

第二,在 Java 1.4 中引入了 NIO 框架(java.nio 包),提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层的高性能数据操作方式。

第三,在 Java 7 中,NIO 有了进一步的改进,也就是 NIO 2,引入了异步非阻塞 IO 方式,也有很多人叫它 AIO(Asynchronous IO)。异步 IO 操作基于事件和回调机制,可以简单理解为,应用操作直接返回,而不会阻塞在那里,当后台处理完成,操作系统会通知相应线程进行后续工作。

7、Java有几种文件拷贝方式?哪一种最高效?【第12讲】

Java 有多种比较典型的文件拷贝实现方式,比如:

利用 java.io 类库,直接为源文件构建一个 FileInputStream 读取,然后再为目标文件构建一个 FileOutputStream,完成写入工作。


public static void copyFileByStream(File source, File dest) throws
        IOException {
    
    
    try (InputStream is = new FileInputStream(source);
         OutputStream os = new FileOutputStream(dest);){
    
    
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0) {
    
    
            os.write(buffer, 0, length);
        }
    }
 }

或者,利用 java.nio 类库提供的 transferTo 或 transferFrom 方法实现。


public static void copyFileByChannel(File source, File dest) throws
        IOException {
    
    
    try (FileChannel sourceChannel = new FileInputStream(source)
            .getChannel();
         FileChannel targetChannel = new FileOutputStream(dest).getChannel
                 ();){
    
    
        for (long count = sourceChannel.size() ;count>0 ;) {
    
    
            long transferred = sourceChannel.transferTo(
                    sourceChannel.position(), count, targetChannel);            sourceChannel.position(sourceChannel.position() + transferred);
            count -= transferred;
        }
    }
 }

当然,Java 标准类库本身已经提供了几种 Files.copy 的实现。

对于 Copy 的效率,这个其实与操作系统和配置等情况相关,总体上来说,NIO transferTo/From 的方式可能更快,因为它更能利用现代操作系统底层机制,避免不必要拷贝和上下文切换。

8、写正则表达式进行手机号匹配(*2)

# 号码规则:
1、第 1 位: 1
2、第 2 位: 39
3、第 3 到第 11 位只要是数字就行.


答案: /^[1]([3-9])[0-9]{
    
    9}$/

(1) /^ - 表示文本开始;
(2) () - 子表达式的开始与结束;
(3) [] - 要匹配里面内容,[0-9]匹配数字范围为0/1/2/3/4/5/6/7/8/9(4) {
    
    n} - 匹配n次,{
    
    9}是匹配9次;
(5) ^ - 字符串开始,\^ - 匹配 ^ 字符本身; $ - 字符串结束。

三、参考

1、Java语法----Java中equals和==的区别
2、你真的懂 == 和 equals 的区别吗?
3、为什么重写了equals()也要重写hashCode()
4、重写equals方法后重写hashCode方法的必要性
5、手机号段正则表达式 (2019-01 最新)
6、正则表达式 - 语法
7、【疑惑整理】【Java】深入浅出HashMap+面试整理

猜你喜欢

转载自blog.csdn.net/HeavenDan/article/details/112728222