BAT内部面试题

时间:2020-11-30作者:猫哥阅读量:116 微信:cms199612

导读:

有许多小伙伴关注BAT内部面试题这一问题。关于此IT猫也是收集了很多材料,加上自己的理解,分享给大家。下面就来一起看一看IT猫收集到的关于《BAT内部面试题》相关内容的分析吧。如果你有更多关于互联网方面的问题,可以联系我。

java

腾讯的Java面试题

TCP和UDP的区别,TCP为什么是三次握手,不是两次。

答:1、因为tcp是全双工协议,区别在于前者可靠,后者不可靠,以及效率更高。

Dubbo面试题

dubbo和dubbox之间的区别?

答:Dubbox 和Dubbo本质上没有区别,名字的含义扩展了Dubbo而已,以下扩展出来的功能

支持REST风格远程调用(HTTP + JSON/XML);

支持基于Kryo和FST的Java高效序列化实现;

支持基于Jackson的JSON序列化;

支持基于嵌入式Tomcat的HTTP remoting体系;

升级Spring至3.x;

升级ZooKeeper客户端;

支持完全基于Java代码的Dubbo配置;

Java List面试题

ArrayList和LinkedList的区别?分别用在什么场景?

答:①ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是对List接口的实现。

前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列

②当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。

③当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。

④从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。

⑤ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。

场景:

链表,插入删除快,查找修改慢。 适用于频繁增删的场景。

数组,查找快,插入删除慢。 适用于频繁查找和修改的场景。

Java Map集合面试题

Collection集合接口和Map接口有什么关系?

答:没有直接关系,但是一些子类会有依赖,Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法。Map接口并不是Collection接口的子接口,但是它仍然被看作是Collection框架的一部分。

Spring面试题

什么是Spring的内部bean?

答:当一个bean只能被某一个类使用时,称该bean为内部bean。

Zookeeper面试题

zookeeper是什么框架?

答:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务

腾讯Java面试题:说说Java中异常的分类。

答:异常分类:

Throwable -> Error,Exception

Error:严重问题,例如内存溢出

Exception ->运行时异常: RuntimeException,编译时异常

AWTError

Dubbo面试题:一般使用什么注册中心?还有别的选择吗?

答:Dubbo 一般用zookeeper做注册中心

还可以用:Redis,数据库,consul

Java List面试题:怎么给List排序?

答:List 如何排序:

①:使用 Collections.sort 默认正序,可以传第二个参数自定义排序

②:自定义bean实现 Comparable 接口。

③: 实现Comparator接口自定义比较器

Java Map集合面试题:你都知道哪些常用的Map集合?

答:HashMap、HashTable、TreeMap、LinkedHashMap

Spring面试题:为什么说Spring是一个容器?

答:Spring的核心理念就是更方便地管理Java Bean,而被管理的Java Bean存缓存在一个Map中,这个Map就可以理解为用来装Java Bean的容器,即IOC容器

1、Java 是如何实现跨平台的?

注意:跨平台的是 Java 程序,而不是 JVM。JVM 是用 C/C++ 开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的 JVM

答:我们编写的 Java 源码,编译后会生成一种 .class 文件,称为字节码文件。Java 虚拟机(JVM)就是负责将字节码文件翻译成特定平台下的机器码然后运行,也就是说,只要在不同平台上安装对应的 JVM,就可以运行字节码文件,运行我们编写的 Java 程序。

而这个过程,我们编写的 Java 程序没有做任何改变,仅仅是通过 JVM 这一 “中间层” ,就能在不同平台上运行,真正实现了 “一次编译,到处运行” 的目的。

2、什么是 JVM ?

解析:不仅仅是基本概念,还有 JVM 的作用。

答:JVM,即 Java Virtual Machine,Java 虚拟机。它通过模拟一个计算机来达到一个计算机所具有的的计算功能。JVM 能够跨计算机体系结构来执行 Java 字节码,主要是由于 JVM 屏蔽了与各个计算机平台相关的软件或者硬件之间的差异,使得与平台相关的耦合统一由 JVM 提供者来实现。

3、JVM 由哪些部分组成?

解析:这是对 JVM 体系结构的考察

答:JVM 的结构基本上由 4 部分组成:

类加载器,在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中

执行引擎,执行引擎的任务是负责执行 class 文件中包含的字节码指令,相当于实际机器上的 CPU

内存区,将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者 PC 指针的记录器等

本地方法调用,调用 C 或 C++ 实现的本地方法的代码返回结果

4、类加载器是有了解吗?

解析:底层原理的考察,其中涉及到类加载器的概念,功能以及一些底层的实现。

答:顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。

类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如 Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。

5、面试官:Java 虚拟机是如何判定两个 Java 类是相同的?

答:Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。比如一个 Java 类 com.example.Sample,编译之后生成了字节代码文件 Sample.class。两个不同的类加载器 ClassLoaderA和 ClassLoaderB分别读取了这个 Sample.class文件,并定义出两个 java.lang.Class类的实例来表示这个类。这两个实例是不相同的。对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常 ClassCastException。

6、类似-Xms、-Xmn这些参数的含义:答:

堆内存分配:

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64

JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。

因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

非堆内存分配:

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;

由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

-Xmn2G:设置年轻代大小为2G。

-XX:SurvivorRatio,设置年轻代中Eden区与Survivor区的比值。

1、sleep( ) 和 wait( n)、wait( ) 的区别?

sleep 方法: 是 Thread 类的静态方法,当前线程将睡眠 n 毫秒,线程进入阻塞状态。当睡眠时间到了,会解除阻塞,进行可运行状态,等待 CPU 的到来。睡眠不释放锁(如果有的话);

wait 方法: 是 Object 的方法,必须与 synchronized 关键字一起使用,线程进入阻塞状态,当 notify 或者 notifyall 被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,释放互斥锁。

2、synchronized 关键字?

答:底层实现:

进入时,执行 monitorenter,将计数器 +1,释放锁 monitorexit 时,计数器-1;

当一个线程判断到计数器为 0 时,则当前锁空闲,可以占用;反之,当前线程进入等待状态。

含义:(monitor 机制)

Synchronized 是在加锁,加对象锁。对象锁是一种重量锁(monitor),synchronized 的锁机制会根据线程竞争情况在运行时会有偏向锁(单一线程)、轻量锁(多个线程访问 synchronized 区域)、对象锁(重量锁,多个线程存在竞争的情况)、自旋锁等。

该关键字是一个几种锁的封装。

3、volatile 关键字?

答:该关键字可以保证可见性不保证原子性。

功能:

· 主内存和工作内存,直接与主内存产生交互,进行读写操作,保证可见性;

· 禁止 JVM 进行的指令重排序。

解析:关于指令重排序的问题,可以查阅 DCL 双检锁失效相关资料。

4、volatile 能使得一个非原子操作变成原子操作吗?

答:能。

一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好是将其设置为 volatile。为什么?因为 Java 中读取 long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)。但是对一个 volatile 型的 long 或 double 变量的读写是原子。

面试官:volatile 修饰符的有过什么实践?

一种实践是用 volatile 修饰 long 和 double 变量,使其能按原子类型来读写。double 和 long 都是64位宽,因此对这两种类型的读是分为两部分的,第一次读取第一个 32 位,然后再读剩下的 32 位,这个过程不是原子的,但 Java 中 volatile 型的 long 或 double 变量的读写是原子的。

volatile 修复符的另一个作用是提供内存屏障(memory barrier),例如在分布式框架中的应用。简单的说,就是当你写一个 volatile 变量之前,Java 内存模型会插入一个写屏障(write barrier),读一个 volatile 变量之前,会插入一个读屏障(read barrier)。意思就是说,在你写一个 volatile 域时,能保证任何线程都能看到你写的值,同时,在写之前,也能保证任何数值的更新对所有线程是可见的,因为内存屏障会将其他所有写的值更新到缓存。

5、ThreadLocal(线程局部变量)关键字?

答:当使用 ThreadLocal 维护变量时,其为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本,而不会影响其他线程对应的副本。

ThreadLocal 内部实现机制:

每个线程内部都会维护一个类似 HashMap 的对象,称为 ThreadLocalMap,里边会包含若干了 Entry(K-V 键值对),相应的线程被称为这些 Entry 的属主线程;

Entry 的 Key 是一个 ThreadLocal 实例,Value 是一个线程特有对象。Entry 的作用即是:为其属主线程建立起一个 ThreadLocal 实例与一个线程特有对象之间的对应关系;

Entry 对 Key 的引用是弱引用;Entry 对 Value 的引用是强引用。

6、我们为什么要使用线程池?核心线程池内部实现了解吗?

答:

减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

可以根据系统的承受能力,调整线程池中工作线程的数目,放置因为消耗过多的内存,而把服务器累趴下(每个线程大约需要 1 MB 内存,线程开的越多,消耗的内存也就越大,最后死机)

面试官:核心线程池内部实现了解吗?

答:对于核心的几个线程池,无论是 newFixedThreadPool() 方法,newSingleThreadExecutor() 还是 newCachedThreadPool() 方法,虽然看起来创建的线程有着完全不同的功能特点,但其实内部实现均使用了 ThreadPoolExecutor 实现,其实都只是 ThreadPoolExecutor 类的封装。

1、解释AOP模块

AOP(Aspect-Oriented Programming)指一种程序设计范型,该范型以一种称为切面(aspect)的语言构造为基础,切面是一种新的模块化机制,用来描述分散在对象、类或方法中的横切关注点(crosscutting concern)。

2、有哪些不同类型的IOC(依赖注入)方式?

构造器依赖注入: 构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。

Setter方法注入: Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。

3、你怎样定义类的作用域?

当定义一个 在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean 定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。

4、Spring框架的事务管理有哪些优点?

它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。

它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如

它支持声明式事务管理。

它和Spring各种数据访问抽象层很好得集成。

5、什么是SpringMVC框架的控制器?

控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。

6、在SpringAOP中,关注点和横切关注的区别是什么?

关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。

横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

1、使用Spring框架的好处是什么?

答:轻量: Spring 是轻量的,基本的版本大约2MB。

控制反转: Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

面向切面的编程(AOP): Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

容器: Spring 包含并管理应用中对象的生命周期和配置。

MVC框架: Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。

事务管理: Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

异常处理: Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

2、 Spring由哪些模块组成?

答:以下是Spring 框架的基本模块:

Core module

Bean module

Context module

Expression Language module

JDBC module

ORM module

OXM module

Java Messaging Service(JMS) module

Transaction module

Web module

Web-Servlet module

Web-Struts module

Web-Portlet module

3、BeanFactory – BeanFactory 实现举例。

答:Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。

最常用的BeanFactory 实现是XmlBeanFactory 类。

4、什么是Spring IOC 容器?

答:Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。

5、IOC的优点是什么?

答:IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。

6、什么是基于注解的容器配置?

答:相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。

开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。

1、什么是Spring MVC框架的控制器?

答:控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。

2、什么是基于注解的容器配置?

答:相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。

开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。

3、怎样开启注解装配?

答:注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 元素。

[email protected] 注解

答:这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,[email protected],容器将抛出BeanInitializationException。

[email protected] 注解

答:@Autowired 注解提供了更细粒度的控制,[email protected]equired一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。

[email protected] 注解

答:当有多个相同类型的bean却只有一个需要自动装配时,[email protected] [email protected] 注解结合使用以消除这种混淆,指定需要装配的确切的bean。

Spring数据访问

1、什么是Mybatis?

(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

(3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。

2、Mybaits的优点?

(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;

(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。

(4)能够与Spring很好的集成;

(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

3、MyBatis框架的缺点?

(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

4、MyBatis框架适用场合?

(1)MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。

(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。

5、MyBatis与Hibernate有哪些不同?

(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。

(2)Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。

(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。

6、Mybatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

1、Mybatis动态sql有什么用?执行原理?有哪些动态sql?

答:Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。

Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

2、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

答:,加上动态sql的9个标签,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。

3、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

答:Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

4、MyBatis实现一对一有几种方式?具体怎么操作的?

答:有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一的类就可以完成;

嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。

5、MyBatis实现一对多有几种方式,怎么操作的?

答: 有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置

6、Mybatis的一级、二级缓存:

答:1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;

3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

1、equal 和 hashcode 作用和区别?

答:首先,我们要明白hashCode()和equals()方法的作用是什么,然后才能说他的区别,说了区别之后在说明使用的时候需要注意的地方,这样的回答思路基本是OK的。

一、hahsCode()和equals()的作用是什么?

hahsCode()和equals()的作用其实是一样的,目的都是为了再java里面比较两个对象是否相等一致

二、hahsCode()和equals()的区别是什么?

我们可以从两个角度分别介绍他们的区别:一个是性能,一个是可靠性。他们的主要区别体现在这里

1.equals()既然已经实现比较两个对象的功能了,为什么还需要hashCode()呢?

因为重写的equals()里一般比较的较为全面和复杂(它会对这个对象内所以成员变量一一进行比较),这样效率很低,而通过hashCode()对比,则只要生成一个hash值就能比较了,效率很高

2.那hashCode的效率这么高,为啥还要用equals()呢?

因为hashCode()并不是完全可靠,非常有可能的情况是,两个完全不同的对象的hash值却是一样的。

所以会有下面三个重要的结论:

*equals()相等的两个对象他们的hashCode()肯定相等,即equals()绝对可靠。

*hahsCode()相同的两个对象,它们的equals()不一定相同。即用hashCode()比较相同的时候不靠谱

*hashCode()不同的两个对象,他们的那么equals()肯定不同。即用hashCode()比较不同的时候肯定靠谱

三、hashCode()和equals使用的注意事项

1.对于需要大量并且快速的对比的话如果都用equals()去做显然效率太低,所以解决方案为:每当需要比较的时候,首先用hahsCode()去对比,而如果hashCode()不一样,则两个对象肯定不一样,此时就没有必要再用equals()比较了;如果hashCode()相同,则这两个对象有可能相同,这时候再去比较这两个对象的equals(),如若equals()也相同,则表示这两个真的相同的,这样既大大提高了效率,又保证了准确性。

2. 事实上,我们平时用的集合框架中的hashMap、hashSet,hashTable 中对key的比较就是使用上述这种方法。

3. 而Obejct默认的equals和HashCode方法返回的是对象的地址相关信息。所以当我们通过new关键字创建了两个内容相同的对象,虽然他们的内容相同,但是他们在内存中分配的地址不同,导致它们的hashCode()不同,这肯定不是我们想要的。所以当我们要将某个类应用到集合中去的时候,就必须重写equals()方法和hashCode()方法。

四、扩展

1.阿里巴巴开发规约明确规定:

*.只要重写了equals()方法,就必须重写hashCode()方法

*.因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法

*.如果对象定义为Map的健,那么就必须重写equals()方法和hashCode()方法

*.String重写了equals()方法和hashCode()方法,所以我们可以非常愉快的时候String对象作为key

2.是不是每个对象都要重写这两个方法,到底什么时候重写?

*.事实上一般情况下,我们并不需要重写这两个方法,只有该类被应用到集合框架中去的时候,才应该重写。

3.我能不能值重写equals()方法,不重写hashCode()方法?

*.如果重写了equals()方法,比如说基于对象的内容实现的,而保留了hashCode()的实现不改变,那么最终出现的情况很可能是,两个对象明明是“相等的”,但是hashCode()却不一样,这不是宝宝想要的

4.为什么需要hashCode

*.通过hashCode可以提高对比的性能

2、如何保证单机保证3w tps 访问量?

答:今天面试被问道一个问题,如何保证单机保证3wtps的访问量?

听到这个问题,第一反应有点蒙,想成了3w的并发量了,想了一下,目前的容器比如tomcat的最大并发量也就几千就扛不住了...

后来我先说IO模型使用NOI,能够处理小数据大并发的请求,然后从代码优化上说要尽量并行处理逻辑,以及优化JVM,调整堆大小,减少FullGC,使停顿时间减少,最终使每个请求的处理时间减少。

但是也知道这个说法挺不搭题的....

后来面试官跟我说从两方面来分析,一方面是从请求上来说,将多个请求合并成一个请求发送,减少请求次数,一方面是把请求都改成异步的,后台处理,让请求过来之后就直接返回成功。

当时感觉这两个方面说的也没问题。毕竟第一次出去面试,脑袋瓜子里有些蒙了,然后后边就是随便聊了一下我个人擅长的方面,我就说了一下自己项目上使用的springCloud,的一些核心组件及注册中心的实现原理等,然后就没有然后了...

感觉这次面试基本是凉了,但是也还好,做好了准备,第一次面试当做总结经验教训了吧。

回来的路上,也一直在思考这个问题,有了一些想法:

1. 首先从题目的说明上,本身存在一些问题,说的是要保证3W的tps,但是如果将请求合并了,是减少了请求次数,但是也打不到3w的tps了啊,这样本身就不符合这个题目的要求了,所以我认为要么修改题目的说明,要么这个3w tps就是一个固定值,无法通过外部优化来减少了,只能从系统内部去优化。

2. 然后从系统优化来说,这个题目本身也存在一定的问题,就是这3w的tps到底是峰值流量还是平时流量,是需要同步给出处理结果,还是可以接受异步的后续返回处理结果。

如果是需要同步给出处理结果,那么就只能从业务处理流程上进行优化,也就是尽量把串行的处理流程改成并行的处理流程,把查询尽量从数据库改到缓存中。但是即使这样,一个需要同步返回结果的3w tps单机处理,每个请求的处理时间=1%3000≈0.00033秒=0.33微妙,感觉在时间上是根本无法处理完一个业务流程的。如果一个业务流程无法处理完的话,那么请求就会出现堆积现象,堆积过多就会出现OOM,内存溢出了...所以我个人感觉这个单机3W同步处理的优化是不符合现实的,只能从业务上去处理,尽量把同步的业务逻辑改成异步的业务逻辑,即使改成异步的业务逻辑,虽然能够支撑住3w的tps,但是因为服务的处理速刷无法达到3wtps的处理速度,那么最终会造成内存的不断消耗,最终导致OOM的出现。

3. 看这个tps到底是峰值还是平时了,如果只是峰值3w,平时很低,而且可以使用异步的话,那么就可以使用MQ了,请求过来直接把请求发送到MQ中去,不处理业务。然后创建消费者去消费这些消息。达到削峰填谷目的。

4. 计算一下,如果一个请求的处理时间是10ms,那么单线程每秒的处理速度=1000%10=100个,采用并行处理,如果是一个四核八线程的处理器,理论上创建16个线程去处理,那么每秒的处理速度=100*16=1600个。不知道这样的计算方法是否正确.

3、讲一下模版模式和策略模式的区别?

答:模板方法模式的主要思想:定义一个算法流程,将一些特定步骤的具体实现、延迟到子类。使得可以在不改变算法流程的情况下,通过不同的子类、来实现“定制”流程中的特定的步骤。

策略模式的主要思想:使不同的算法可以被相互替换,而不影响客户端的使用。

4、redis和MQ如何平滑的扩容与缩容?

答:MQ的消息是存放在内存或者磁盘中的,在缩减集群数量时,必须要迁移节点的数据。增加节点时,要重新配置集群。这么看来是无法平滑缩容和扩容的。

5、MQ的消息生产比消费速度快得多,有什么解决方案吗?

生产消息比消费速度快得多,这个本身是没问题的,因为MQ的一个作用就是削峰。

如果要提高消费速度,可以增加多个消费者

6、feign如何实现负载均衡,与Ribbon的负载均衡有什么区别?

答:

Feign 一般用 Ribbon 来实现负载均衡。

与 Ribbon 负载均衡的区别?我觉得2个是不一样的东西吧,Feign 已经包含了 Ribbon,需要配合使用,一般生产环境用的是 Spring Cloud 技术来整合的,当然也可以用其他技术来替代。

Feign 作为客户端

Ribbon 作为负载均衡

Eureka 作为注册中心

Zuul 作为网关

Security 作为安全 OAuth 2 认证

首先得知道 Feign 和 Ribbon 是什么,然后具体怎么实现。

Feign:申明式 Web 服务客户端

申明式:接口声明、Annotation 驱动

Web 服务:HTTP 的方式作为通讯协议

客户端:用于服务调用的存根

假设,有一个Java 接口 UserService, Feign 可以将其声明它是以 HTTP 方式调用的。

Ribbon:客户端负载均衡器,可以对 HTTP 和 TCP 客户端的行为进行控制。

关于《BAT内部面试题》的相关内容,就给大家讲到这里。如果您想了解更多互联网解决方案内容请关注本站。

本文链接地址:https://www.xiaozeseo.com/JAVA/300.html 未经允许禁止转载。

相关栏目

推荐内容

热点内容