热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

字节跳动Java后端面试真题,看完你学会了吗,「附面试福利」

前言;之前有好多朋友给我留言说想去字节跳动,今天就给大家分享几道字节跳动的面试真题给大家,文末有福利哦。一.谈谈你对Java平台的理解?Java是解

 

前言;

之前有好多朋友给我留言说想去字节跳动,今天就给大家分享几道字节跳动的面试真题给大家,文末有福利哦。

 

 


一. 谈谈你对Java平台的理解? "Java 是解释执行",这句话正确么?

典型回答:

Java本身是一种面向对象的语言,最显著的特点有两个方面,一个是所谓的"书写一次,到处运行";能够非常容易地获得跨平台能力;另外就是垃圾收集器(GC),Java通 过垃圾收集器回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。我们日常接触到JRE或者JDK。JRE也就是Java运行环境,包含了JVM和Java类库,以及一些模块等。而JDK可以看作是JRE的一个超集,提供了更多的工具,比如编译器各种诊断工具。

"对于Java是解释执行"这句话,这个说法不准确。我们开发的Java的源代码,首先通过Javac编译成为字节码,然后在运行时通过Java虚拟机内嵌的解释器将字节码转换为最终的机器码。但是常见的JVM,比如我们大数据情况使用的0racleJDK提供的HostpotJVM,提供了JIT编译器,就是通常所说的动态编译器,JIT能够在运行时将热点代码(高频调用的方法和代码块)编译成机器码,这种情况下部分热点就属于编译执行,而不是解释执行。这样类似于缓存技术,运行时在遇到热点代码可以直接执行,而不是先解释在执行。

知识扩展:

在运行时 , JVM通过类加载器加载字节码,解释或者编译执行。就像我们前面提到的,主流的Java版本中,如JDK8实际是解释和编译混合的一种模式,即所谓的混合模式。JIT编译器分为多种模式(Server模式C1ient模式AOT模式)通常运行在Server模式的JVM,会进行上万次调用以收集足够的信息进行高效编译,client模式这个门限是1500次。

Oracle Hostpot JVM内置了两个不同的JIT compiler,C1对应 前面说的client模式,适用于对于启动速度敏感的应用,比如普通Java桌面应用;C2对应Server模式,它的优点是为长时间运行的服务器端应用设计的。

Java虚拟机启动时, 可以指定不同的参数对运行模式进行选择。比如,执行"-Xint",就是告诉JVM只进行解释执行,不对代码进行编译,这种模式抛弃了JIT可能带来的性能优势。毕竟解释器是逐条读入,逐条解释运行的。与其相对性的,还有一个"Xcomp"参数,这是告诉JVM关闭解释器,不要进行解释执行,或者叫做最大优化级别。那你可能会问这种模式是不是最高效啊?简单来说,还真未必。"-Xcomp" 会导致JVM启动变慢非常多..

除了日常最常见的Java使用模式,其实还有一种新的编译方式,即所谓的AOT,直接将字节码编译成机器码,这样就避免了JIT预热等各方面的开销,比如Oracle JDK 9就引入了实性质的AOT特性,并且增加了jaotc工具。

另外,JVM作为一个强大的平台,不仅仅只有Java语言可以运行在JVM上,本质上合规的字节码都可以运行,Java语言自身也为此提供了便利,我们可以看到类似ClojureScala Groovy JRuby Jython等 大量JVM语言,活跃在不同的场景。


二. 请对比Exception和Error,另外,运行时异常与一般异常有什么区别?

典型回答:

Exception和Error都是继承了Throwable类,在Java中只有Throwable类型的实例才可以被抛出或者捕获,它是异常处理机制的基本组成类型。Exceptoin和Error体现了Java平台设计者对于不同异常情况的分类。Exception是程序正常运行中,可以预料的意外情况,可以并且应该被捕获,进行相应处理。Error是指在正常情况下,不大可能出现的情况,绝大部分的Error都会导致处于非正常的不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如.OutofMemoryError之类,都是Error的子类。

Exceptoin又分为可检查异常和不检查异常,可检查异常在代码里必须显示地进行捕获处理,这是编译器检查的一部分。不检查异常就是所谓的运行时异常,类似于Nul1PointerException ArrayIndex0utofBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来进行判断是否需要捕获,并不会在编译期强制要求。

知识扩展:

在开发中尽量不要捕获类似Exceptio这样的通用异常,而是应该捕获特定异常.这是因为我们在日常的开发和合作中,我们读代码的机会往往超过写代码,软,件工程是门协作的艺术,所以我们有义务让自己的代码能够直接地体现出尽量多的信息,而泛泛的Exception之类,恰恰隐藏了我们的目的。另外,我们也要保证程序不会捕获到我们不希望捕获的异常。比如,你可能更希望RuntimeException 被扩散出来,而不是被捕获。

在开发中不要生吞异常。这是异常处理中要特别注意的事情,因为很可能会导致非常难以诊断的诡异情况。生吞异常,往往是基于假设这段代码可能不会发生,或者感觉忽略异常是无所谓的,但是千万不要在产品代码做这种假设!如果我们不把异常抛出来,或者也没有输出日志之类,程序可能在后续代码以不可控的方式结束。没有人能够轻易判断究竟是哪里出了异常,以及是什么原因产生了异常。

在开发中不要输出标准错误(STERR),因为有时候你很难判断出到底输出到哪里去了。尤其是分布式系统,如果发生异常,但是无法找到堆栈轨迹,这纯属是为诊断设置障碍。所以最好使用产品日志,详细地输出到日志系统里。

Throw early,catch late。在开发中可能会出现各种情况,比如获取配置失败之类的。在发现问题的时候,第一时间抛出,能够更加清晰地反映问题,这是Throw early。 catch late就是 我们经常烦恼的问题,捕获异常后,需要怎么处理?最差的方式,就是我们前面提到的"生吞异常",本质上就是掩盖问题。如果实在不知道如何处理,可以选择保留原有异常的cause信息,直接再抛出或者构建新的异常抛出去。在更高层,因为有了清晰的(业务)逻辑,往往会更清楚合适的处理方式是什么。

有时候,我们会根据需要自己定义异常,这个时候除了保证提供足够的信息,还需要考虑两点。一是否需要定异常CheckedException,因为这种类型的设计初衷是为了从异常情况恢复,作为异常设计者,我们往往有充足信息进行分类。在保证诊断信息足够的同时,也要考虑避免包含敏感信息,因为那样可能会导致潜在的安全问题。如果我们看Java的标准类库,你可能注意到类似java. net. ConnectException,出错信息是类似"Connection refused", 而不包含具体的机器名IP端口等,一个重要的考量就是信息安全。类似的情况在日志系统中也有,比如,用户数据一般是不可以输出到日志里面的。

try-catch代码段会产生额外的性能开销,或者换个角度来说,它往往会影响JVM对代码进行优化,所以建议仅捕获有必要的代码段.尽量不要一个大的try包住整段代码,与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句要低效。

额外:

NoClassDeF oundError和ClassNotFoundException的区别?

首先NoClassDeFoundError是一个错误,ClassNotFoundException是一个异常。ClassNotFoundException的产生原因,Java支持使用Class. froName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时拋出ClassNotFoundException异常。

另外还有一个导致ClassNotFoundException的原因就是,当一个类已经被某个类加载器加载到内存中,此时另一个类加载器又尝试着动态地从同一个包中加载这个类。

NoClassDeFoundError产生的原因在于:如果JVM或者ClassLoader实例尝试加载类的时候找不到类的定义。例如要查找的类在编译的时候是存在的,运行的时候,找不到了。这个时候就会导致NoClassDefFoundError.造成该问题的原因可能是打包过程中漏掉了部分类,或者jar包出现损坏或者篡改。解决这个问题的办法就是查找那些在开发期间存在与类路径下,但在运行期间却不在类路径下的类。


三. 对比Hashtable、HashMap、TreeMap有什么不同?

典型回答:

HashTable HashMap TreeMap都是最常见的一些Map实 现,是以键值对的形式存储和操作数据的容器类型。

HashTable是早期Java类库提供的一个哈希表实现,本身是同步的,不支持nu11键和值,由于同步导致的性能开销,所以已经很少被推荐使用。

HashMap是应用更加广泛的哈希表实现,行为大致.上与HashTable- -致,主要区别在于HashMap不是同步的,支持nul1键和值等。通常情况下, HashMap进行put或者get操作,可以达到常数时间的性能,所以它是绝大部分利用键值对存储场景的首选,比如,实现一个用户ID和用户信息对应的运行时存储结构。

TreeMap则是基于红黑树的一种提供顺序访问的Map,和HashMap不同,它的getremove之类操作都是0(long(n)的时间复杂度,具体顺序可以由指定的Comparator来决定或者根据键的自然顺序来判断。

知识扩展:

HashMap实现原理是经常被问到的一个问题,以下基于JDK1.8分析。

1. 内部存储

HashMap的内部存储是一个数组,数组的元素Node实现了Map.Entry接口(hash, key, value, next) , next非空时指向定位相同的另一个Entry,如图:

 

JDK 8之前,其内部是由数组+链表来实现的,而JDK 8对于链表长度超过8的链表将转储为红黑树。

2. 容量(capacity)和负载因子(loadFactor)

简单的说, capacity就是数组的大小,loadFactory就是数组填满程度的最大比列。当数组中的元素的数目大于capaci ty*loadFactor时就需要扩容,调整数组的大小为当前的2 倍。同时初始化容量的大小也是2的次幂(大于等于设定容量的最小次幂),则数组的大小在扩容前后都将是2的次幂。默认的容量为16,负载因子为0.75。

3. put方法的大致的思路


  • 如果key的值为null,则将该键值对添加到table[0]处,遍历该链表,如果有key为null,则将value替换。
  • 如果key不为null,获取key的hashCode值,经过indexFor()方法运算得到的值作为标识,但由于hashCode的值并不唯一,经过运算获取的值也不能保证唯一(哈希冲突),所以,经过以上运算得来的数值只能作为数组的索引。
  • 当通过索引定位到这个节点时,在遍历该链表,判断是否存在相同的key对象,如果存在就用新的value覆盖旧的value
  • 如果不存在,就创建一个Entry对象添加到table[i]处,如果table[i]已经存在其他元素,那么新Entry对象将会保存在链表的表头,通过next指针指向原有的Entry对象,形成链表结构。
  • 当链表的结构太长时(默认超过8个元素),链表就会转为红黑树。

4. get方法的大致的思路


  • 对key进行nu11检查。如果key是nu11,table[0]这个位置的元素将被返回
  • key的hashcode() 方法被调用,然后计算hash值。
  • indexFor (hash, table. length)用来计算要获取的Entry对象在table数组中的精确的位置(使用刚才计算的hash值)
  • 在获取了table数组的索引之后,会迭代链表,调用equals()方法检查key的相等性,如果equals()方法返回true,get方法返回Entry对象的value,否则,返回null。

四. ArrayList Vector LinkedList的 区别?

典型回答:

这三者都是实现集合框架中的List,也就是所谓的有序集合,因此具体功能也比较类似,比如都提供按照位置进行定位添加或者删除的操作,都提供迭代器以遍历其内容等。但因为具体的设计区别在行为性能线程安全等方面,表现又有很大不同。

Vector是Java早期提供的线程安全的动态数组,如果不需要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector内 部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组以满时,会创建新的数组,并拷贝原有数组数据。

ArrayList是应用更加广泛的动态数组实现,它本身不是线程安全的,所以性能要好很多。与Vector近似,ArrayList也是可以根据需要调整容量,不过两者的调整逻辑有所区别, Vector在扩容时会提高1倍,而ArrayList则是增加50%。

LinkedList顾明思议是Java提供的双向链表,所以它不需要像.上面两种那样调整容量,它也不是线程安全的。

Vector和ArrayList作为动态数组,其内部元素以数组形式顺序存储的,所以非常适合随即访问的场合。除了尾部出入元素和删除元素,往往性能会相对较差,比如我们在中间位置插入一个元素,需要移动后续所有元素。而LinkedList进行节点插入删除却要高效得很多,但是随即访问性能则要比动态数组慢。


文末福利

限于篇幅,今日份大厂面试真题到此为止;需要的更多的Java后端面试题、视频学习资料的朋友可以关注我的工种号【Java周某人】即可领取

我给大家整理了一份详细的大厂面试题资料,这份pdf文档资料长达四百多页,可想而知他是真的很全面很全面了,分专题整理,直击你的知识盲区,查漏补缺,剑指offer

 

 

 

 

 


推荐阅读
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 在配置Nginx的SSL证书后,虽然HTTPS访问能够正常工作,但HTTP请求却会遇到400错误。本文详细解析了这一问题,并提供了Nginx配置的具体示例。此外,还深入探讨了DNS服务器证书、SSL证书的申请与安装流程,以及域名注册、查询方法和CDN加速技术的应用,帮助读者全面了解相关技术细节。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 本文详细介绍了如何在 Linux 系统上安装 JDK 1.8、MySQL 和 Redis,并提供了相应的环境配置和验证步骤。 ... [详细]
  • oracle c3p0 dword 60,web_day10 dbcp c3p0 dbutils
    createdatabasemydbcharactersetutf8;alertdatabasemydbcharactersetutf8;1.自定义连接池为了不去经常创建连接和释放 ... [详细]
  • 1.创建目录mkdir-phomerocketmqnamesvr1data&&mkdir-phomerocketmqnamesvr1log&&mkdir-phomerocketm ... [详细]
  • 本教程详细介绍了如何使用 Spring Boot 创建一个简单的 Hello World 应用程序。适合初学者快速上手。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • SecureCRT是一款功能强大的终端仿真软件,支持SSH1和SSH2协议,适用于在Windows环境下高效连接和管理Linux服务器。该工具不仅提供了稳定的连接性能,还具备丰富的配置选项,能够满足不同用户的需求。通过SecureCRT,用户可以轻松实现对远程Linux系统的安全访问和操作。 ... [详细]
  • 本文深入解析了通过JDBC实现ActiveMQ消息持久化的机制。JDBC能够将消息可靠地存储在多种关系型数据库中,如MySQL、SQL Server、Oracle和DB2等。采用JDBC持久化方式时,数据库会自动生成三个关键表:`activemq_msgs`、`activemq_lock`和`activemq_ACKS`,分别用于存储消息数据、锁定信息和确认状态。这种机制不仅提高了消息的可靠性,还增强了系统的可扩展性和容错能力。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
author-avatar
渴求打怪升级
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有