Java面试题整理《上》

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

要找工作啦,在这里记录下整理的面试题。Java体系还是很庞大的,我将其分为Java语言部分(JavaSE、JavaEE等官方方面),非Java语言部分(数据库,WEB前端,redis,框架等技术方面)和项目部分。

一、Java基础部分

  1. 简单介绍下Java的跨平台原理

    不同的操作系统的操作指令集不同,所以做程序开发的时候需要根据不同的操作系统开发程序。比如想要程序支持MacOS、Windows和Linux就要开发三套不同的程序代码。这会导致开发成本成倍提升,所以很多程序都只开发了windows版本。这是相对于桌面程序来说的,如果是WEB应用程序就没有这个烦恼,这也是WEB开发这么流行的原因。
    Sun公司开发了适用于不同操作系统及位数的JVM虚拟机来屏蔽系统之间的差异并提供了统一的接口,对于Java程序而言,只需要遵循Java语言规范,就可以在所有的操作系统上运行程序。

  2. Java中int数据占用几个字节?

    int数据占用4个字节,这在哪个位数操作系统上都是一样的,主要是为了跟CPU的字长一致,目的当然是提高处理速度。

  3. Java面向对象有哪些特征?

    主要有四个特征:抽象,封装,继承和多态。

    抽象的目的是忽略与主题无关的其他信息,使用abstract关键字修饰,规定抽象方法只能为public/protected,被修饰的类不能被实例化,只允许通过继承的方式来实现。

    封装的意思就是想让你看到就让你看到不想让你看到就不让你看到,使用private关键字实现,当你需要对属性进行修改的时候就使用类中的get/set方法,使用public关键字。这是出于安全和易用性方面的考虑。

    继承的意义在于不需要重复造轮子,子类继承父类就可以得到除了private之外的父类的全部属性和方法(父类的构造方法除外)。需要知道的是Java只支持单继承,这是出于对继承链可能会出现过于复杂的情况的设计方案,如果想实现类似C++语言的多继承,可以使用接口来实现。还需要注意这几点,如果没有指定父类,那么类的直接父类是java.lang.Object;一般继承会导致重写,子类有时候会需要重写父类的方法,在重写时必须保证方法名和形参列表相同,返回值类型和异常类型子类需要小于父类;访问权限,子类需要大于父类。

    多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用只有在程序运行期间才会确定,在Java中通过继承的方式来实现多态,即父类接口引用变量指向子类或实现类的实例对象,这样程序调用的方法在运行期才会动态绑定引用变量所指向的具体实例对象的方法,也就是内存里正在运行的对象方法。。比如公司规定十点上班工作,但并不会对程序员说你要敲代码,并不会对HR说你要检查邮件这个工作的具体实现。需要注意的是多态是方法的多态而不是属性的多态,多态是在继承的基础上实现的。

  4. 接口和抽象的区别是什么?

    两者都是Java面向对象的重要实现。它们都声明方法而不去实现,本质的区别在于抽象类是一个类,而接口是其他的类型,在OC中都没有接口这一说,而是使用protocol。抽象类除了不能实例化之外跟普通的类没有区别,而接口完全不存在方法的实现,不能有构造器,只能使用public访问修饰符,没有main方法等。接口提供抽象方法,类通过interface关键字对接接口,重写抽象方法实现对应业务逻辑以此对外提供服务。比如Map接扣作为一个容器就会提供put方法来往容器中填充值,get方法获取容器中某一个值,size属性获取容器大小,remove方法来删除容器中的值。接口除了做规范之外还是多继承在Java中的解决方案,另外接口也是各种框架和API的实现,比如RedisTemplate就是封装了jedis,如果在项目中使用redis,直接通过注入RedisTemplate接口就可以完成对redis的操作。

  5. 已经有基本类型了,为什么还需要包装类型呢?

    Java提供了八种基本类型,每一种类型都会有一个对应的包装类型,比如boolean-Boolean,JVM会在两者之间自动转换,这是JDK1.5做的改变。

    Integer i = 1; //自动装箱,编译时会调用Integer.valueOf(1)

    int j = i; //自动拆箱,编译时调用intValue();

    值得注意的是自动装箱时系统会创建缓存,并将当前数据添加到缓存中,有两个作用,第一是为了缓解使用包装类型导致数据存储会略微变慢的问题,第二是解决了包装类型判断是否相等的问题。

    Java是一门面向对象的语言,基本数据类型并不具备面向对象的特征,这会导致数据存储的问题,例如在处理空值的时候,使用Integer时需要判断null,使用int的时候需要判断0,而在数据库中通常默认值为0。这会导致在数据库中存储id的时候,id类型为bigint,当控制类方法的接收值为long而不是Long的话会报错。使用Long表示类的ID的时候,在需要判断类是否存在只需要判断为null就可以了,而且使用包装类型就可以通过其提供的方法MAX和MIN获取最大值和最小值等。

  6. 说一下"=="和equals方法究竟有什么区别?

    ==用于判断两个变量是否相等。变量可以分为基本数据类型和引用数据类型,如果是引用数据类型需要比较引用的内存首地址,如果是基本数据类型直接比较值。

    equals方法是判断两个对象的某些特征是否一致,通过重写对象的equals方法。

    如何理解?通过观察源码会发现,equals方法会首先判断两个比较值类型是否一致,然后再比较数值或字符,例如Integer类型会自动拆箱为int类型进行比较,String会将字符串拆分成字符。

  7. 讲一下String和StringBuilder的区别(final)?StringBuffer和StringBuilder的区别?

    java提供了三个类String、StringBuilder和StringBuffer来表示和操作字符串。字符串即是由多个字符(char)的集合。

    String是内容不可变的字符串(private final char value[])

    StringBuilder和StringBuffer继承自AbstractStringBuilder类(char[] value);

    因此拼接字符串的时候:

String:String s = "a"+"b";
StringBuilder sb = new StringBuilder();
sb.apend("a").apend("c")

拼接字符串的时候不能使用String进行拼接,要使用StringBuilder和StringBuffer。前者效率高但线程不安全,后者效率低但线程安全。

  1. 简单说一下java中的集合

    java中的集合主要分为value和key-value两种。
    
    存储值分类list和set,list重复有序,set不可重复无序。并且set根据equals和hashcode判断,如果对象存储在set中,则必须重写这两个方法。
    
    存储键值在java中是称之为map,在OC语言中叫字典。
    
  2. List常用的ArrayList和LinkedList的区别和使用场景?

    ArrayList底层使用数组(private transient Object[] elementData;)
    
    LinkedList底层使用链表(transient Node<E> first; transient Node<E> last;)
    
    数组是一块连续的内存,因此插入和删除的时候需要移动内存。由于有这个特点所以说数组查询元素快,插入和删除删除慢。
    
    链表的原理是在当前元素中存放上一个和下一个元素的地址,查询时从头部开始一个个找,因此查询效率慢,由于做修改的时候不需要做内存移动操作,只需要改变引用指向即可完成,所以插入和删除操作效率高。
    
    不难看出链表和数组是相反的,所以它们的使用场景就呼之欲出了,而由于数据库操作的特殊性(查询占90),所以一般我们会选择ArrayList做数据保存的容器。
    
  3. 讲一下HashMap和 HashTable的区别?HashTable和ConcurrentHashMap的区别?

    首先HashTable是不可以使用null作为key或者value的,HashTable在存储数据的时候会返回synchronized。因此可以得出结论HashTable安全但效率不高。
    
    如果想既效率高又安全,可以使用ConcurrentHashMap并发容器的方式,原理是将整个Map分成N个Segment(类似HashTable不加锁),提供相同的线程安全,但是效率提升N倍默认为16倍。
    
  4. 实现一个拷贝文件的工具类使用字节流还是字符流?

    字节流和字符流都可以实现对文件的拷贝,如果确认不包含例如图片和音频这样特殊的文件,使用字符流即可,否则应该使用字节流。
    
  5. 线程的几种实现方式,启动方式?

    两种实现方式:继承Thread类和实现Runnable接口。一般采用实现接口的方式,因为java只支持单继承。
Thread thread = new Thread(new MyThread());//MyThread类继承了Thread对象或Runnable接口
thread.setName("xiaoming");//通过设置线程名称来区分线程
thread.start();//通过start()方法来启动线程,但实际执行的方法是run方法。run()方法是Thread类和Runnable接口自带的方法,需要重写和实现run()。
  1. 线程池的作用
  • 线程过多的话会导致系统运行缓慢甚至崩溃,所以需要限制线程的个数
  • 线程池如果每次都创建或者销毁会导致资源的浪费

什么是设计模式?常用的设计模式有哪些?

设计模式是前人经验所得的可以反复使用,解决特定问题的设计方法。

  • 单例模式是最常见的设计模式之一,它的作用是保证某一实例的唯一性。具体实现就是在类中定义一个实例对象并提供一个公开方法获取该实例,然后将构造器私有化,如果需要使用该实例的话,只能通过提供的公开方法而不能new出这个类,这样每次得到的实例就是同一个实例。单例分为懒加载和立即加载两种模式,懒加载在创建对象的时候就加载实例,立即加载在需要的时候才加载实例。
  • 工厂模式,SpringIoC中的BeanFactory,MyBatis中的SqlSessionFactory就都是工厂模式的实现
  • 代理模式,SpringAOP是通过动态代理实现
  • 观察者模式,Spring中的listener实现ApplicationListener
  • 模板模式,Spring集成了JdbcTemplate、RedisTemplate、SolrTemplate、JmsTemplate
  • 适配器模式,SpringMVC中的处理器映射器HandlerMapper

二、J2EE部分

  1. 说一下你对servlet的理解?或者servlet是什么?

    Java Servlet是使用J2EE服务端程序,后端代码通过实现Servlet接口并重写HTttpServlet的doGet/doPost方法来进行对数据库和浏览器之间的交流,Servlet程序需要运行在支持Java程序的应用服务器中,比如tomcat,jetty等。

  2. 简单说一下servlet的生命周期?

    Servlet是一个接口规范,所以有比较明确的生存期定义,接口中的init,service和destory方法进行表述。

  3. Servlet API中forward()与redirect()的区别?

    forward就是转发,是服务端行为因此只发送一次请求也不会改变url地址,redirect是重定向,是客户端行为会改变url地址并且发送两次请求

  4. JSP和Servlet有哪些相同点和不同点?

    JSP是Servlet的扩展,所有的jsp文件都会被编译成一个继承自HttpServlet的类,因为servlet输出html比较麻烦,所以设计出jsp。

  5. JSP有哪些内置对象?作用分别是什么?

    九个内置的对象:

    • request 用户端请求,此请求会包含来自GET/POST请求的参数
    • response 网页传回用户端的回应
    • pageContext 网页的属性是在这里管理
    • session 与请求有关的会话期
    • application servlet正在执行的内容
    • out 用来传送回应的输出
    • config servlet的构架部件
    • page JSP网页本身
    • exception 针对错误网页,未捕捉的例外

    四大作用域:

    • pageContext 整个page页面
    • request(HttpServletRequest) service方法
    • session(HttpSession) 第一次调用request.getSession()方法时
    • application(ServletContext) 整个WEB应用程序
  6. 说一下Session和Cookie的区别?你在项目中都有哪些地方使用了?

    session和cookie都是HTTP的会话跟踪技术,是为了解决HTTP无状态的特性而设计的技术。cookie在客户端浏览器记录信息认证身份,session在服务端记录信息确认身份。session通过在cookie中存放的sessionId来保证信息的一致性。

    session和cookie的区别如下

  • 由于cookie数据保存在浏览器中,因此有安全和数据限制的问题,考虑到这种情况应该使用session保存数据
  • session数据存在服务器上,当访问比较多的情况下会耗费服务器资源,考虑到这种情况应该使用cookie

    购物车是最好的cookie技术实现场景,用户登录信息的存储是最好的session技术实现场景。

    我在做用户注册生成短信验证码和solr异步删除索引库数据,静态页面生成的时候使用过jmsTemplate.send()方法,该方法中有一个内部类(new MessageCreator()),此类中接收session参数,然后通过这个session创建消息实例设置消息并返回。

  1. HTTP中GET和POST请求的区别
    用户通过不同的请求方式完成对资源的不同操作,比如PUT请求就是代表对请求资源的增加,DELETE请求就是对请求资源的删除。为了方便开发,一般我们只使用GET和POST方式就可以了。两者本质上都是TCP链接,区别在于:
  • get请求时,地址栏会显示请求信息,以?开头,多个参数以&连接,而post请求在request body中
  • get请求由于浏览器对地址长度的限制而导致传输的数据有限,post则没有这个限制
  • 由于请求信息会暴露所以get请求会有安全隐患
  • get产生一个TCP数据包,浏览器会将http header和data数据一起发送,等待服务器响应200并返回数据;post请求产生两个数据包,浏览器会发送header,等待服务器响应100 continue,浏览器才会发送data,最后等待服务器响应200和请求的数据
  • 对于get和post的区别,有一个比较有趣的比喻。get传递数据如同写在脸上,post传递数据如同方法肚子里,脸上自然不能放太多东西也不能放隐私的东西,而肚子里就无所谓了。
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
18天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
45 14
|
28天前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
22天前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
27 6
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
53 4
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
105 4
|
2月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
113 1
Java面试题之Java集合面试题 50道(带答案)
|
2月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
64 5