前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >阿里《JAVA实习生入职测试题—2019最新》之答案详解(连载一)

阿里《JAVA实习生入职测试题—2019最新》之答案详解(连载一)

作者头像
NaughtyCat
发布2020-10-09 16:42:31
2900
发布2020-10-09 16:42:31
举报
文章被收录于专栏:开心的平凡酱开心的平凡酱

力争清晰完整准确

1、String类为什么是final的

首先分析String的源码:

代码语言:javascript
复制
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
  • 类被final关键字限定,说明它不可以被继承,没有子类。即持有一个String对象的引用,它必然是String类,而不会是其他的类。
  • value[]是用来存储值的,被final关键字修饰,说明这个数组不可被其它数组替换—即数组的地址不可变更,但是数组的每个元素的值可以变更

private 限定符,保证String字符串数组的值不可在类外被修改。由于未对外暴露可修改的接口,所以String的值一旦被创建,即不可被修改。

  • 线程安全

因为字符串是不可修改的(只能读不能写),多个线程可以共享同一个字符串实例

  • 字符串常量池可以大大提高时空间效率

字符串常量池,详情请移步  https://segmentfault.com/a/1190000009888357

2、JDK8的HashMap的源码,实现原理,底层结构

  HashMap的Hash冲突解决,后面单独会写一篇博客。

  ConcurrentHashMap的锁分段,大厂很喜欢问(最近华为电话面试问过我),简单说一句,就是hashMap的数据是一个数组,用多个锁来锁,一个锁锁一个节点的数据链。

不像以前一个锁锁住整个数组,多个线程可分段访问这些数据,自然效率就高了

  • 首先看Node的源码
代码语言:javascript
复制
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

   HashMap用 transient Node<K,V>[] table 存值,本质上是链表数组(哈希数组+链表+红黑树),是Hash散列的,即数组非紧密排列,有空隙,详见下图

HashMap结构
HashMap结构

                              图01

为什么有红黑树,看put(新增)的源码片段,如下:

代码语言:javascript
复制
  else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);

TreeNode定义的源码片段,如下:

代码语言:javascript
复制
    static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
        TreeNode<K,V> parent;  // red-black tree links
        TreeNode<K,V> left;
        TreeNode<K,V> right;
        TreeNode<K,V> prev;    // needed to unlink next upon deletion
        boolean red;
        TreeNode(int hash, K key, V val, Node<K,V> next) {
            super(hash, key, val, next);
        }
  • 容量及动态扩容
代码语言:javascript
复制
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

默认容量-16。resize时,newCap = oldCap << 1( 2进制,左移1位,即*2,旧的容量翻倍,容量可能不是2的幂,视就又容量情况而定)

  • 新增元素
代码语言:javascript
复制
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    1)如果以前这个key有值,put 操作会用新值替换旧值。

    2)Hash冲突怎么解决

 hash(散列),就是key和存储位置有个映射关系f,我们称之为hash函数。hash冲突,就是不同的key,根据hash函数算出来的存储位置相同,后面添加的元素就和原来的hashCode冲突了,所以要重新按照一定规则计算新的存储位置。普通HashMap(java 8的HashMap结构如“图1”,有红黑树)结构如下图:

java8 中的HashMap为了提高查找效率,当链表冲突过高,大于阈值时,会将链表节点转化成红黑树节点

  • 装载因子
代码语言:javascript
复制
static final float DEFAULT_LOAD_FACTOR = 0.75f;

load factor默认0.75 ,这个和概率统计有关(Hash冲突概率最低),详见 http://en.wikipedia.org/wiki/Poisson_distribution

为了减少冲突,当hashMap的数组长度 >  临界值 就会触发扩容,所有元素rehash(重新计算hashCode和存储位置)再放到扩容后的容器中,因为涉及到计算、数据查找、内存拷贝、移动等操作,非常耗时。

临界值 = current capacity * current load factor。默认临界值 = DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR = 16 x 0.75 = 12时,就会触发扩容操作。

*****************************************************************************************************

精力有限,想法太多,专注做好一件事就行

  • 我只是一个程序猿。5年内把代码写好,技术博客字字推敲,坚持零拷贝和原创
  • 写博客的意义在于锻炼逻辑条理性,加深对知识的系统性理解,锻炼文笔,如果恰好又对别人有点帮助,那真是一件令人开心的事

*****************************************************************************************************

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档