java面试技术准备

面试开始会让自我介绍,主要业务架构和技术架构两部分。业务架构一般不会深究,但要面试官听明白,并且一般面试官会顺着问是如何根据这些业务去设计技术架构的。

技术架构部分,会根据自我介绍中提到的技术点问,是为什么使用这些技术,解决了哪些问题,碰到哪些困难,是如何思考和解决的,最后再顺带一些技术本身底层的设计方面的问题:

例如:有redis,会问哪些场景用,解决了什么问题,数据量有多少,用的过程出现过哪些问题,怎么去定位解决的,还有它的hash原理等。诸如此类的问题。总结了面试官最喜欢问的方面有mq,jvm,多线程,锁机制等。

不管哪个技术点,能答到面试官无法在这个问题上问下去了,或者能答到计算机硬件上就过了。 有不清楚的可以直接回答,有一些不会的不影响整个面试。

Redis

Spring与Redis集成之aop整合方案:

参考链接:https://blog.csdn.net/zhanngle/article/details/41077423?utm_source=blogxgwz2

java使用redis缓存可以使用jedis框架

       应用场景:

  1. 热点数据(经常会被查询,但是不经常修改或删除数据)
  2. 计数器 (统计点击数等应用)
  3. 队列(功能类似消息队列)
  4. 位操作(大数据处理)用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等;
  • 原理:

Redis内构建一个足够长的数组,每个数组元素只能是0和1,然后这个数组的下标index来表示用户的id(必须是数字),显然几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统,上面的场景也能实现。

  • 分布式锁与单线程机制

验证前端重复请求

秒杀系统,基于Redis是单线程的特征,防止出现数据库“爆破”

全局增量ID生成,类似“秒杀”

  • 为什么使用Message Queue(消息队列)

解耦、异步、削峰

JVM

  • Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。

① Java源文件—->编译器—->字节码文件

② 字节码文件—->JVM—->机器码

 

(3) 三种JVM:

     ① Sun公司的HotSpot;

     ② BEA公司的JRockit;

     ③ IBM公司的J9 JVM;

     在JDK1.7及其以前我们所使用的都是Sun公司的HotSpot,但由于Sun公司和BEA公司都被oracle收购,jdk1.8将采用Sun公司的HotSpot和BEA公司的JRockit两个JVM中精华形成jdk1.8的JVM。

 

JVM调优主要就是优化 Heap堆 和 Method Area 方法区

静态变量+常量+类信息+运行时常量池存在方法区中,实例变量存在堆内存中。

基本类型的变量和对象的引用变量都是在函数的栈内存中分配。

(5) Heap 堆

       堆这块区域是JVM中最大的,应用的对象和数据都是存在这个区域,这块区域也是线程共享的,也是 gc 主要的回收区,一个 JVM 实例只存在一个堆类存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分为三部分:

① 新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。

如果出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:

    a.Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。

    b.代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)

大对象的概念?

违反了SRP原则(就一个类而言,应该只有一个引起它变化的原因,每个变化就是类的一个职责,如果一个类有多个职责,那么引起类变化的原因就有多个,增加了类之间的耦合)

  • 面向对象设计原则:

SRP单一职责原则:就一个类而言,应该仅有一个引起它变化的原因;

OCP开放-封闭原则:软件实体(类、模块、函数)应该可以扩展的,但不可以修改;

LSPLiskov替代原则:子类型必须能够替代它们的基类型;

DIP依赖倒置原则:抽象不应该依赖于细节,细节应该依赖于抽象;

ISP接口隔离原则:不应该强迫客户依赖与它们不用的方法。接口属于客户,不属于它所在的类层次结构;

REP重用发布等价原则:重用粒度就是发布粒度。

CCP共同封闭原则:包中 所有类应该对于同一类性质的变化应该是共同封闭的。一个变化若对包产生影响,则将对包中所有的类产生影响。而对其它的包不造成影响。 

CRP共同重用原则:一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。 

ADP无环依赖原则:在包的依赖关系图中不允许存在环。 

SDP稳定依赖原则: 易变化包不应该依赖稳定包。 

SAP稳定抽象原则:朝着抽象方向扩展。

② 养老区用于保存从新生区筛选出来的 JAVA 对象,一般池对象都在这个区域活跃。

③ 永久区是一个常驻内存区域,用于存放JDK自身所携带的 Class,Interface 的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭 JVM 才会释放此区域所占用的内存。

如果出现java.lang.OutOfMemoryError: PermGen space,说明是Java虚拟机对永久代Perm内存设置不够。原因有二:

     a. 程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。

     b. 大量动态反射生成的类不断被加载,最终导致Perm区被占满。

JVM垃圾回收 

GC(Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法叫收集器,由于GC需要消耗一些资源和时间;java在对对象的声明周期特性进行分析后,按照新生代、旧生代的方式对对象进行收集,以尽可能的缩短GC对应用造成的暂停。

  1. 对新生代的收集称为minor GC;
  2. 对旧生代对象的收集称为Full GC;
  3. 程序中主动调用System.gc()强制执行的gc称为Full GC。

不同的对象引用类型,GC会采用不同的方法进行回收,JVM对象的引用分为了四种类型:

  1. 强引用:默认情况下,对象采用的均为强引用(这个对象实例没有其他对象引用,GC才会被回收)
  2. 软引用:软引用是java中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下,才会gc)
  3. 弱引用:在GC时一定会被GC回收
  4. 虚引用:由于虚引用只是用来得知对象是否被GC

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。

 https://baijiahao.baidu.com/s?id=1605937053950156833&wfr=spider&for=pc

Scavenge GC(针对新生区)

    一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

 

Full GC

    对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:

· 年老代(Tenured)被写满

· 持久代(Perm)被写满 

· System.gc()被显示调用 

·上一次GC之后Heap的各域分配策略动态变化

 

1)检测垃圾机制
  Java运行时所加载的数据, 如类信息、实例对象信息等会占用系统内存, 所幸的是Java有个强大的垃圾收集器, 在内存不够分配对象的时候会触发GC。
  检测垃圾的方法常见的有两种:1. 引用计数法;2. 可达性分析算法。

可达性分析算法 
  主流的JVM基本都使用可达性分析算法来判断对象是否存活,通过一系列“GC Roots”的对象作为起始点向下搜索,搜索所走过的路径为引用链,当一个对象没有任何引用链与GC Roots相连,代表该对象不再被使用,将其判定为可回收的对象。

2)回收垃圾机制

标记-清除算法 
  先标记待回收的对象,然后再对标记的对象进行清除。
这种算法缺点 :

    • 标记和清除两个过程, 效率不高
    • 标记清除后会产生大量不连续内存碎片, 多次进行标记和清除回收后可能会导致以后程序在运行过程中需要分配大对象时,无法找到足够的连续内存而不得不提前出发GC,而GC需要耗时间。

复制算法 
  复制算法是将内存分成两块,一块存储程序运行分配的对象,一块是空闲区域。当存储对象的内存区域用完了,会将此区域存活的对象复制到另一块空闲区域,然后再把已使用的内存空间一次清理掉。

复制算法实现简单、高效。但代价有点大了,可用内存缩小为原来的一半,以“空间换取时间”。

标记-整理算法

  标记-整理算法是对原有标记-清除算法进行的改造,不是直接对可回收对象进行清理,而是让所有存活对象都向另一端移动,然后直接清理掉端边界以外的内存。

  1. 在java多线程中,有synchronized关键字来实现线程间的同步互斥工作,那么其实还有一个更优秀的机制去完成这个“同步互斥”工作,他就是Lock对象,用得最多的是重入锁ReentrantLock和读写锁ReentrantReadWriteLock。他们具有比synchronized更为强大的功能,
    并且有嗅探锁定、多路分支等功能。

重入锁ReentrantLock:

在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,不然会造成锁永远无法释放,其他线程永远进不来的结果。

读写锁ReentrantReadWriteLock:

其核心就是实现读写分离的锁。在高并发访问下,尤其是读多写少的情况下,性能要远高于重入锁。synchronized、ReentrantLock,同一时间内,只能有一个线程进行访问被锁定的代码,那么读写锁则不同,其本质是分成两个锁,即读锁、写锁。在读锁下,多个线程可以并发的进行访问,但是在写锁的时候,只能一个一个的顺序访问。

口诀:读读共享(只有所有线程都是读才是共享),写写互斥,读写互斥(重要:这个一定得互斥)。

 

  1. 代理模式的定义代理对象控制对原对象的引用。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

为其他对象提供一种代理以控制对这个对象的访问

 

  1. 比特币系统中的数据是由一个个区块存储,并且通过哈希的方式将一个个区块连接起来,这样就形成了一个区块的链条,把它称为区块链。

点对点的网络、时间戳、加密技术、工作量证明等,所有这些技术不仅仅可以应用于数字货币,还能够应用到其他领域,这些技术综合提炼之后,就提出了区块链概念,即区块链不是一个单一的技术,它是一系列技术的集合。

 

  1. 工厂模式
  1. 简单工厂模式

特点:它是一个具体的类,非接口或抽象类。有一个重要的create()方法,利用if或switch创建产品并返回。Create方法通常是静态的,所以也称之为静态工厂。

缺点:扩展性差(增加一个产品类还需要修改工厂类方法);不同的产品需要不同的额外参数的时候不支持。

举个栗子:

https://www.cnblogs.com/zailushang1996/p/8601808.html

  1. 工厂方法模式

模式描述:提供一个用于创建对象的接口(工厂接口),让其实现类(工厂实现类)决定实例化哪一个类(产品类),并且由该实现类创建对应类的实例。

模式作用:

可以一定程度上解耦,消费者和产品实现类隔离开,只依赖产品接口(抽象产品),产品实现类如何改动与消费者完全无关。

可以一定程度增加扩展性,若增加一个产品实现,只需要实现产品接口,修改工厂创建产品的方法,消费者可以无感知(若消费者不关注具体产品是什么情况)。

可以一定程度增加代码的封装性、可读性。清楚的代码结构,对于消费者来说很少的代码量就能完成很多工作。

另外,抽象工厂才是实际意义的工厂模式,工厂方法只是抽象工厂的一个比较常见的情况。

 

适用场景:

消费者不关心他所要创建的对象的类(产品类)的时候;

消费者知道他所要创建的对象的类(产品类),但不关心如何创建的时候。

模式要素

提供一个产品类的接口。产品类均要实现这个接口(也可以是abstract类,即抽象产品)
提供一个工厂类的接口。工厂类均要实现这个接口(即抽象工厂)
由工厂实现类创建产品类的实例。工厂实现类应有一个方法,用来实例化产品类

举个栗子:

https://www.cnblogs.com/zailushang1996/p/8601808.html

  1. 抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类;

类型:创建类模式;

类图:

 

抽象工厂模式与工厂方法模式的区别:

抽象工厂模式是工厂方法模式的升级版,他用来创建一组相关或者相互依赖的对象。他与工厂方法的模式区别在于,工厂方法模式针对的是一个产品登记结构;而抽象工厂模式则是针对的多个产品等级结构。

抽象工厂模式的优点:

抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

抽象工厂模式的缺点

产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

适用场景

       当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。

总结

       无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底是工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

       所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。

 

https://www.cnblogs.com/zailushang1996/p/8601808.html

  1. 单例模式

核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点

应用:Windows系统的任务管理器、回收站,网站计数器(否则难以同步)、线程池、应用程序的日志应用、web应用配置对象的读取(资源共享);

 

1. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~ 

2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。

4. 应用程序的日志应用,一般都采用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。

7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

9. HttpApplication 也是单例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.

 

总结以上,不难看出:

  单例模式应用的场景一般在以下条件发生

  (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。

  (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

public class SingletonInner {

//内部类实现单例模式 * 延迟加载,减少内存开销

private static class SingletonHolder {

private static SingletonInner instance = new SingletonInner(); }

//私有的构造函数

private SingletonInner() {}

public static SingletonInner getInstance() {

return SingletonHolder.instance;

}

protected void method() {

System.out.println("SingletonInner");

}

}

  1. 什么是负载均衡?

  当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能。那么,在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台服务器的负载情况将请求分配给某一台后端服务器去处理。

 

  1. 五大框架(springMVC,Struts2,spring,mybatis,hibernate)
  1. springMVC

Springmvc是string框架的一个模块,它是一个基于MVC设计模式的前端web层框架,主要作用就是对前端请求进行处理。

备注:MVC指的就是model(业务模型),view(视图),controller(控制器)

  1. Struts2

它是一个基于MVC设计思想的前端web层框架,主要作用就是对前端请求进行处理。它的核心是拦截器,但它的前端控制器是一个过滤器。

springMVC与Struts2比较:

  1. Springmvc的入口是一个servlet前端控制器,Struts2入口是一个filter过滤器;
  2. Struts2通过在action类中定义成员变量接受请求参数,Struts2只能使用多例模式管理action;springMVC是通过在controller中定义形参接受请求参数,springMVC可以使用单例模式管理controller。
  3. springMVC是基于方法开发的,注解开发中使用requestMapping将url和方法进行映射,如果根据url找到controller类的方法生成一个handler处理器对象(只包括一个method)。Struts2是基于类开发,每个请求过来创建一个action实例,实例对象中有若干方法。
  1. Spring

Spring的核心有很多,其中主要且常用的就是AOP,IOC,DI。也就是面向切面编程、控制反转、依赖注入。Spring一般作为容器管理其他框架。例如常见的web层框架(Struts2、springmvc)和持久层框架(mybatis、hibernate),一般都由spring来管理。

  1. Mybatis

Mybatis是一个优秀的ORM框架,应用在持久层,它对jdbc的操作数据库进行封装,使开发者只需要关注sql本身,而不需要花费精力去处理例如注册驱动、创建connection、等jdbc繁杂的过程代码,一般使用mapper代理的方式开发,直接在xml中写sql。

  1. hibernate

Hibernate是轻量级的持久层解决方案,是一个关系数据库ORM框架, 对JDBC访问数据库的代码做了封装.我们可以很容易的对数据库进行增删改查操作。

 

  1.  Zookeeper是一个高效的分布式协调服务,可以提供配置信息管理、命名、分布式同步、集群管理、数据库切换等服务。它不适合用来存储大量信息,可以用来存储一些配置、发布与订阅等少量信息。Hadoop、Storm、消息中间件、RPC服务框架( rpc就是自定义了协议和传输通道,将远程的调用伪装成本地调用, 所以效率的关键就是中间的流程)、分布式数据库同步系统,这些都是Zookeeper的应用场景。

Zookeeper集群中节点个数一般为奇数个(>=3),若集群中Master挂掉,剩余节点个数在半数以上时,就可以推举新的主节点,继续对外提供服务。

  1. Java反射机制

 

1、获取Class对象的三种方式

1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3 通过Class类的静态方法:forName(String  className)(常用)

注意:在运行期间,一个类,只有一个Class对象产生。

 

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。

反射机制提供的功能:在运行时判断任意对象的所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  1. F5负载均衡

是一款网络负载均衡器,就是讲负载进行平衡、分摊到多个单元上进行执行;

  1. 红黑树

红黑树又称红黑二叉树;红黑树的左旋、右旋、重新着色原理与java实现;

红黑树的五点规则:

  1. 每个节点非黑即红;
  2. 根节点是黑色的;
  3. 每个叶节点是黑色的(NIL节点,空节点);
  4. 一条路径上不能出现相邻节点同一颜色;
  5. 从任一节点到每个叶子的所有路径都包含相同数目的黑色节点;

红黑树的检索效率:O(lg n)

  1. 计算机常见的五大算法

贪婪算法、动态规划算法、分治算法、回溯算法、分支界限算法;

  1. 数据结构与算法

 

数据之间的关系称为逻辑结构。通常分为四种基本结构:

  1. 集合 

结构中的数据元素属于同一种数据类型

  1. 线性结构

结构中的数据元素之间存在一对一的关系

  1. 树形结构

结构中的元素存在一对多的关系

  1. 图形结构或网状结构

结构中的数据元素存在多对多的关系

数据结构在计算机中有两种不同的存储方法:

顺序存储结构:用数据元素在存储器中的相对位置来表示数据元素之间的逻辑关系;

链式存储结构:在每一个元素中增加一个存放地址的指针,用此指针表示数据元素之间的逻辑关系;

时间复杂度,空间复杂度

 

//冒泡排序改进1

  public void bubbleSort_improvement_1(){

     int temp;

     int len = array.length;

    

     for(int i=0;i<len-1;i++){

         boolean exchange = false;  //设置交换变量

         for(int j=1;j<len-i;j++){

            if(array[j-1]>array[j]){  //如果前一位大于后一位,交换位置

                temp = array[j-1];

                array[j-1] = array[j];

                array[j] = temp;

               

                if(!exchange) exchange =true;  //发生了交换操作

            }

         }

         System.out.print("第"+(i+1)+"轮排序结果:");

         display();

         if(!exchange) break;  //如果上一轮没有发生交换数据,证明已经是有序的了,结束排序

     }

   }

  1. 哈希表

哈希表也叫做散列表,是根据关键码值(key value)而直接进行访问的数据结构。就是通过把关键码值映射到表中一个位置来访问记录,以加快查找速度。这个映射函数叫做散列函数,存放记录的数组叫做散列数组。

 

  1. 敏捷开发

敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发,Scrum流程

在敏捷实施过程当中,有四种会议,分别是计划会、每日站会、回顾会、评审会,其中数计划会最为重要

 

  1. Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

  1. java集合

集合分为collection和map两类

 

常用的ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap、TreeMap; 

List是有序的(存取顺序),可以装重复元素,有索引 
Set是无序的(存取顺序),不能重复,无索引值.

 

  1. TreeMap和HashMap的区别和共同点
  1. 实现    

TreeMap:SortMap接口,基于红黑树;

HashMap:基于hash散列表实现;

  1. 存储

TreeMap:默认按键升序排列;

HashMap:随机存储;

  1. 遍历

TreeMap:Iterator遍历是排序的

HashMap:Iterator遍历是随机的

  1. 性能损耗

TreeMap:插入、删除

HashMap:基本无

  1. 键值对

TreeMap:键、值都不能为null

HashMap:只允许键、值均为null

  1. 安全

都是非并发安全Map

一般情况下我们选用HashMap,因为HashMap的键值对在取出时是随机的,其依据键的hashCode和键的equals方法存取数据,具有很快的访问速度,所以在Map中插入、删除及索引元素时其是效率最高的实现。而TreeMap的键值对在取出时是排过序的,所以效率会低点。

  1. Java接口
  1. 接口中可以定义常量,不能定义变量,如果在接口中定义属性,那么通过反编译它会自动用public static final修饰,接口中的属性都是全局静态常量,接口中的常量必须在定义时指定初始值;
  2. 接口中所有的方法都是抽象方法,接口中的方法都会自动用public abstract修饰,即接口中只有全局抽象方法;
  3. 接口不能实例化,接口中不能有构造方法。
  4. 接口之间可以同extends实现继承关系,一个接口可以继承多个接口,但接口不能继承类;
  5. 接口的实现类必须实现接口的全部方法,否则必须定义为抽象类。

接口,笔者更倾向于为协议。一个自己默认的编码规范。使用接口可以达到一定程度的解耦合作用。例如在接口中定义一些全局变量。在发生需求变化时。只需要改变接口中的值即可。

注:关于此处变量的全局定义,也可以写在抽象类中,但是接口的加载效率更高,建议接口。

  1. 接口的作用是什么?

笔者认为接口是一种协议。例如两个开发者,开发时间完全不一致,那么需要两个人的配合开发,则需要一个人接口写好,定义好其中所有的变量命名规范、函数定义规范。具体实现类的开发人员则只需要按照接口实现相应功能即可。

  1. 为什么不在一个类是直接实现相应的方法,而是需要先进行接口抽象?

①首先是关于全局变量的定义,目的已经很清楚了。

②其次是说明一下接口的真正作用是建立在很多的对象类、并且类同时拥有很多的方法(需要实现的功能)。这种情景下,使用接口可以非常明显的感觉到接口的作用。

  1. 面向对象的特性-多态

面向对象编程有三大特性:封装、继承、多态

封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。

继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。同时继承也为实现多态做了铺垫。

Java实现多态有三个必要条件:继承、重写、向上转型。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备既能调用父类的方法和子类的方法。

  1. String、Stringbuffer、StringBuilder的区别

String(字符串常量)

StringBuffer字符串变量(线程安全)

StringBuilder字符串变量(非线程安全)

StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。

StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符序列的变长数组。

在大部分情况下,StringBuilder > StringBuffer。这主要是由于前者不需要考虑线程安全。

使用策略:

  1. 基本原则:如果要操作少量的数据,用String;单线程操作大量的数据,用StringBuilder;多线程操作大量的数据,用StringBuffer。
  2. 不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。
  3. 为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。

4)StringBuilder一般使用在方法内部来完成类似"+"功能,因为是线程不安全的,所以用完以后可以丢弃。StringBuffer主要用在全局变量中。

5)相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用StringBuilder;否则还是用StringBuffer。

 

  1. Mysql的增量备份和全量备份

mysql数据库的备份是万分重要的,以防在数据库表丢失或损坏情况出现,可以及时恢复数据

MySQL备份(Backup)与 恢复(Restore)汇总
1.mysqldump
2.mysqlbackup
3.mysqlhotcopy
4.xtrabackup/innobackupex
5.cp

  1. 数据库事务四大特性

原子性、一致性、隔离性、持久性

  1. Cassandra

Cassandra使用PRIMARY KEY分发数据。每个主键值使用单个分区。这意味着它每个分区只能存储一行数据。

如果你有大量数据由数千或数百万行组成,则不是很有用。为了适应这种情况,Cassandra表可以拥有一个唯一值的CLUSTERING KEY,并使Cassandra能够为每个分区存储多行。

 

Cassandra 的数据模型的基本概念:

  1. Cluster : Cassandra 的节点实例,它可以包含多个 Keyspace
  2.  Keyspace : 用于存放 ColumnFamily 的容器,相当于关系数据库中的 Schema 或 database
  3. ColumnFamily : 用于存放 Column 的容器,类似关系数据库中的 table 的概念

4. SuperColumn :它是一个特列殊的 Column, 它的 Value 值可以包函多个 Column5. Columns:Cassandra 的最基本单位。由 name , value , timestamp 组成

 

 

 

  1. SSTable的特点

首先明确一下上文中提到的SSTable特点:

  1. 需要存储的<键,值>格式的字节数据
  2. 键可以重复,键值对不需要对齐,即可以是任意长度的
  3. 需要支持高效的随机读取操作

 

 

新人期: 完成一项具体的任务.
成熟期: 完成一个项目的整体把控.

  1. 你在技术方面要有过人之处
  2. 经常和你的队员沟通,打成一片
  3. 不仅仅是要管理他们,你还要帮助你的团队成员,引导他们去完成目标
  4. 为他们争取更多的利益
  5. 发掘他们的长处相信他们
    发展期: 引领一个专业方向的发展.
    事业期: 引领一个或多个专业方向的团队, 将技能转化为实际生产力.
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CSDN砖家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值