why哥被阿里一道基础面试题给干懵了,一气之下写出万字长文。 (6)

简介: why哥被阿里一道基础面试题给干懵了,一气之下写出万字长文。 (6)

就看第一句我圈起来的话。后面的描述都是围绕着这句话在展开描述。


Java 虚拟机的 tableswitch 和 lookupswitch 指令,只支持 int 类型。


好,那我现在来问你:switch 语句的表达式可以是哪些类型的值?注意我说的是表达式。


这个答案在《Java 语言规范》里面也写着的:


image.png


你看,8 种基本类型已经支持了char、byte、short、int 这4 种,而这 4 种都是可以转化为 int 类型的。


而剩下的 4 种:double、float、long、boolean 不支持。


为什么?


你就想,你就结合我前面讲的内容,把你的小脑壳子动起来,为什么这 4 种不支持?


因为 double、float 都是浮点类型的,tableswitch 和 lookupswitch 指令操作不了。


因为 long 类型 64 位了,而tableswitch 和 lookupswitch 指令只能操作 32 位的 int 。

这两个指令对于 long 是搞不动的。


而至于 boolean 类型,还需要我说嘛?


你拿着 boolean 类型放到 switch 表达式里面去,你不觉得害臊吗?


你就不能写个 if(boolean) 啥的?


然后你又发动你的小脑壳子想:对于 Character、Byte、Short、Integer 这 4 个包装类型是怎么支持的呢?


上个图,左上是 java 文件,右上是 jad 文件,下面是字节码:


image.png


拆了个箱,实际还是用的 int 类型,这个不需要我细讲了吧?


于是你接着想对于 String 类型是怎么支持的呢?


微信图片_20220426223228.png


它会先转 hashCode。hashCode 肯定是稀疏的,所以用 lookupswitch。


然后在用 var3 这个变量去做一次 switch,经过转化后 var3 一定不是稀疏的,所以用 tableswitch:


image.png


你再多想一步,因为是用的 String 类型的 hashcode,那如果出现了哈希冲突怎么办?


看一下这个例子:



image.png


冲突了就再配一个 if-else 。


不用多说了吧。


最后,你再想,这个枚举又是怎么支持的呢?


比如下面这个例子,看字节码,只看到了使用了 tableswitch:


image.png


它们分别长这样的:


微信图片_20220426223336.png


上面的 SwitchEnumTest.class 文件看不出来什么道道。


但是下面的 SwitchEnumTest$1.class 文件里面还是有点东西的。


可以看到静态代码块里面有个数组,数组里面的参数是枚举的类型,然后调用了枚举的 ordinal 方法。这个方法的返回值是枚举的下标位置。


在 class 文件里面获取的信息有限,需要祭出 jad 文件来瞅一眼来:


微信图片_20220426223353.png


上面就是 java 文件对应的 jad 文件。


标号为 ① 的地方是我们传入的 switch 里面的表达式,线程状态枚举中的 RUNNABLE。


标号为 ② 的地方是给 int 数值中的位置赋值为 2。那么是哪个位置呢?


RUNNABLE 在线程状态枚举中的下标位置,如下所示,下标位置是1:


image.png


编号为 ③ 的地方是把 int 数值中下标为 1 的元素取出来?


我们前面刚刚放进去的。取出来是 2。


于是走到编号为 ④ 的逻辑中去。执行最终的输出语句。


所以写到这里,我想我更加能明白著名程序员沃·滋基索德的一句话:


相对于 String 类型而言,枚举简直天生就支持 Switch 操作。


奇怪的知识点


再送给你一个我在写这篇文章的时候学到的一个奇怪的知识点。


我们知道 switch 的表达式和 case 里面都是不支持 null 的。


你有没有想过一个问题。case 里面为什么不支持 null?如果表达式为 null ,我们就拿着 null 去 case 里面匹配,这样理论上做也是可以做的。


好吧,应该也没有人想这个问题。当然,除了一些奇奇怪怪的面试官。


这个问题我在《Java 语言规范》里面找到了答案:



image.png


the designers of the Java programming language。


我的妈呀,这是啥啊。


Java 编程语言设计者,这是赏饭吃的祖师爷啊!


《Java 语言规范》里面说:根据 Java 编程语言设计者的判断,抛出空指针这样做比静默地跳过整个 switch 语句或选择在 default 标签(如果有)里面继续执行语句要好。


别问,问就是祖师爷觉得这样写就是好的。


一个基本上用不到的知识点送给大家,不必客气:


image.png


目录
相关文章
|
5月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
4月前
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
3月前
|
负载均衡 架构师 Cloud Native
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选  CP 还是 AP?为什么?
|
4月前
|
SQL Java 数据库连接
阿里腾讯互联网公司校招 Java 面试题总结及答案解析
本文总结了阿里巴巴和腾讯等互联网大厂的Java校招面试题及答案,涵盖Java基础、多线程、集合框架、数据库、Spring与MyBatis框架等内容。从数据类型、面向对象特性到异常处理,从线程安全到SQL优化,再到IOC原理与MyBatis结果封装,全面梳理常见考点。通过详细解析,帮助求职者系统掌握Java核心知识,为校招做好充分准备。资源链接:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
131 2
|
6月前
|
存储 NoSQL Redis
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 +  无锁架构 +  EDA架构  + 异步日志 + 集群架构
|
6月前
|
存储 算法 架构师
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
|
8月前
|
存储 SQL 算法
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
例如,在一个有 10 个节点的系统中,增加一个新节点,只会影响到该新节点在哈希环上相邻的部分数据,其他大部分数据仍然可以保持在原节点,大大减少了数据迁移的工作量和对系统的影响。狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由”。在 3 - 5 年的中期阶段,随着业务的稳定发展和市场份额的进一步扩大,订单数据的增长速度可能会有所放缓,但仍然会保持在每年 20% - 30% 的水平。
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
|
8月前
|
算法 NoSQL 应用服务中间件
阿里面试:10WQPS高并发,怎么限流?这份答案让我当场拿了offer
在 Nacos 的配置管理界面或通过 Nacos 的 API,创建一个名为(与配置文件中 dataId 一致)的配置项,用于存储 Sentinel 的流量控制规则。上述规则表示对名为的资源进行流量控制,QPS 阈值为 10。resource:要保护的资源名称。limitApp:来源应用,default表示所有应用。grade:限流阈值类型,1 表示 QPS 限流,0 表示线程数限流。count:限流阈值。strategy:流控模式,0 为直接模式,1 为关联模式,2 为链路模式。
阿里面试:10WQPS高并发,怎么限流?这份答案让我当场拿了offer