Java 面试问题汇总

 

 

面试问题汇总

2019.4月份

​ Java问题汇总

  • jvm加载类的机制

Jvm是通过classLoader来加载java类文件,jvm会把java中的类加载到内存中去,通过jvm中的解析器把类文件解析成要执行的汇编语言,java中有三大类:1系统类、2扩展类、3程序员定义的类

  • jvm内存调优相关问题
  1. stackOverflow异常 一般什么情况下出触发的? 一般是栈内存中的局部变量过爆,导致内存溢出。出现递归方法,参数过多,递增过深,没有释放。
  2. 有遇到OutOfMemory(内存溢出)问题? permgen space、heap space错误、

常见原因:

内存加载数据量太大,一次性从数据库取太多数据,集合类中的对象引用,未清空,GC不能回收。

代码中循环产生过多重复对象,启动参数堆内存值太小。

  • 堆内存设置的参数是什么?

-Xms 设置堆的最小空间大小 -Xmx 设置堆的最大空间大小

JVM各参数名称及配置:

-Xms :初始推大小、一般物理内存的1/64(<1GB)

-Xmx: 最大推大小、物理内存的1/4(<1GB)

-Xmn: 年轻代大小(1.4or lator)

-XX:NewSize 设置年轻代大小

-XX:MaxNewSize 年轻代最大值

-XX:PermSize 设置持久代(perm gen)初始值

-XX:MaxPermSize 设置持久代最大值

-Xss 每个线程的堆栈大小

  • Java中的堆和栈的区别

栈(操作系统):有系统自动分配释放、存放函数、局部变量的值等,分配的内存大小在jvm机加载的时候已经开辟了空间,栈的默认空间是2M,如果超出这个大小,就会内存溢出异常。

堆(操作系统):一般有程序员分配释放、若不释放,程序结束时由系统自动回收,类似于new 一个对象会分配空间,大小无法确定,类似链表结构。

区别:栈速度快,灵活性小,堆速度慢,灵活度大。

栈:都是存储局部变量,推:存储的都是对象

  • Java 实现分布式锁的方法?

数据库乐观锁(version版本号来控制)、redis/zookeeper(这两种最常用)/ memcache

  • Java 多线程

实现多线程四种方法:继承Thread类/实现Runable接口/Callable/ExecutorService(后面两种有返回值,前面没有返回值)

sleep和wait方法区别:sleep不会释放对象锁和资源,wait会释放锁和资源。

java中的如果保持一个线程在另一个行程后面执行,可以使用join方法,此方法内部也调用了wait方法,说明在等待排队时也会释放对象资源的。

start和run方法区别:start会创建新的线程再去调用run方法,run方法只会在当前执行的线程中运行。

如何解决线程阻塞问题:如果是I/O的话,很难排查,如果是调用了wait、sleep、join方法可以使用interrupt方法来中断线程、抛出中断异常InterruptedException ,再去唤醒线程。

volatile的使用:多个线程使用一个方法的变量时,其中有一个线程改变了变量值,就会同步到主内存中去,其他线程就可以得知这个变量的值,一般用来控制多并发请求控制数量。

作用:一是保证共享变量对所有线程的可见性;二是禁止指令重排序优化

线程通过yield方法来暂停

 

线程池:ThreadPoolExecutor,来创建多种线程

线程池的优点:

1、可以有效的提高线程使用率,降低系统的开销。

2、防止过多的线程数消耗内存,导致服务器崩溃。

有四种线程池:

newFixedThreadPool: 创建固定线程数量的线程池

newSingleThreadExecutor: 创建单一线程的池

newCachedThreadPool: 创建线程数量自动扩容, 自动销毁的线程池

newScheduledThreadPool: 创建支持计划任务的线程池

多线程经常遇到的问题是:死锁、活锁、饥饿。

死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,会阻塞。

为什么会产生死锁:

① 因为系统资源不足。② 进程运行推进的顺序不合适。 ③ 资源分配不当。

避免死锁产生方法:

1.一个请求就封锁一个资源,使用完了就释放资源。

2.避免无限期等待:一个线程占用资源时间过长,设置等待时间,在规定的时间内释放占用过长的资源的进程

 

活锁:就是多个线程在使用资源的时候,你让我我让你,一直处于循环不间断的状态,这样很消耗cpu内存的,且不会阻塞。

如何解决活锁:1.使用第三方检测机制(jConsoles ,jVisalVM)调优工具

 

饥饿:多个线程始终无法获得资源。

为什么会产生饥饿锁:①系统的高优先等级的进程占用了低等级的资源。② 线程在等待的过程中也调用了wait方法一直处于等待。

如何解决饥饿锁 : 公平锁,相互分配均匀。

 

 

​ spring问题汇总

  1. springmvc 主要配置大量的配置文件

原理:SpringMVC提供了总开关DispatcherServlet;请求处理映射器(Handler Mapping)和处理适配器(Handler Adapter),视图解析器(View Resolver)进行视图管理;动作处理器Controller接口(包含ModelAndView,以及处理请求响应对象request和response),配置灵活,支持文件上传,数据简单转化等强大功能。​Java 面试问题汇总_第1张图片

  1. spring boot

原理:在spring基础之上简化了spring的配置工作,约定大于配置,更方便的注重业务的开发工作,基本上没有什么配置,都是通过注解的形式来完成项目,使我们的代码更加简单和结构更加清晰,通过springbootApplication注释来启动一个类。

  1. spring cloud 微服务

一系列框架有序集合,利用springboot来简化分布式系统的开发操作,包括服务注册(Eureka(尤里卡)),配置中心,负载均衡等.

有ribbon来控制负载均衡,微服务之间通过feign进行通信处理业务(fegin其实也用了ribbon,通过了http中的TCP请求)

注册中心流程:spring clound有个eureka服务注册中心,所有的模块化功能都要注册到这个服务容器里面来,eureka提供一个服务端 注解@EnableEurekaServer来启动服务。其他的项目通过配置文件来eureka.client.serviceUrl.defaultZone=eureka里面的地址,来达到注册到服务中心去,eureka访问的页面中就会出现注册的实例。

 

Hystrix负责处理服务超时熔断,turbine监控服务之间的调用和熔断指标。

Hystrix断路器:用于处理分布式系统延迟和容错的开源库,在分布式系统中经常会出现调用失败,超时,异常等,hystrix保障了这种情况下,不会导致整体服务失败,避免级联故障,“断路器” 本身是一种开关装置,当发现故障,断路器中turbine就会监控到,向调用的方法返回一个预期的,不会长时间等待和抛出异常的结果。

是给第一页方法或第一页方法可能调用的其他方法留出时间,并导致异常恢复。

spring gateway:中提供了一个gateway(路由器)功能主要过滤一些url。

Ribbon和Nginx区别:

Ribbon是客户端负载均衡,一般搭配springcloud,dubbo微服务来通过rpc运程调用本地实现本地负载均衡,它是从eureka注册中心服务器端获取注册信息列表缓存到本地,实现本地轮询负载均衡策略的,它是基于http和tcp客户端的。

Nginx:主要是服务器端,通过服务器端来实现负载均衡

Zookeeper:负载均衡是可以调控的,而Nginx只能调权重

  1. dubbo微服务

原理:是一个阿里开源的分布式微服务架构框架,基于RPC调用的。

服务治理,服务监控。

支持的协议:dubbo/http/webserice/rmi/redis/rest/memcache等

dubbo内置服务器:spring容器、jetty、log4j,dubbon服务容器是跟spring boot差不多,有个简单的Main方法,用于启动服务。

dubbo有哪几种节点:provider(服务提供方)、consumer(服务器消费方)、register(服务注册中心)、monitor(服务器监控)、container(服务运行容器)

 

注册中心服务流程图:

Java 面试问题汇总_第2张图片

dubbo使用什么注册中心:zookeeper(推荐)、其他:redis/simple不推荐。

dubbo配置方式:1.spring配置、2.java API 配置。

dubbo:核心配置有哪些?:dubbo:service(服务配置)、dubbo:regiser(注册中心)、dubbo:provider(提供方配置)、消费方、method(方法)等

 

  1. spring cloud和dubbo区别

dubbo 是 基于 RPC 远程过程调用 ,srping cloud 是基于 http rest api 调用

​ 持久层问题汇总

mybatis:目前用的3.0版本开发

mybatis plus 是在mybatis的一个增强版吧,简化了开发、集成 spring,可以简化代码

 

hibernate:

 

​ 数据库问题汇总

  • mysql数据:
  1. 数据库隔离级别有4种:

Read uncommitted(读不提交)Read committed(读提交),

Repeatable read(不可重复读),Serializable(持久化,最高的级别,性能比较低)

  1. mysql索引类型?

1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引

语法:直接创建:CREATE INDEX index_name ON table(column(length));修改表结构:ALTER TABLE table_name ADD INDEX index_name ON (column(length))

加索引应该要注意的:避免频繁添加索引,对查询频率高的字段添加索引,针对order by group by的字段添加索引。

组合索引:主要是针对多个字段来添加同一个索引,索引名称已多个字段来命名如:name_age_address,且会以第一个索引来查询,才能满足第二个 如:(1,2,3) 必须满足1,才能继续查询2,3。

ALTER TABLE myIndex ADD INDEX name_city_age (vc_Name(10),vc_City,i_Age);

  1. mysql分区分表

分区:就是把一个数据表的文件和索引分散存储在不同的物理文件中.

mysql支持的分区类型包括Range(常用)、List、Hash、Key。

create table user(

id int not null auto_increment, username varchar(10), primary key(id)

)engine = innodb charset=utf8

partition by range (id)(

partition user_1 values less than (10), partition user_2 values less than (20)

);

分表:就是把一个表分成多张表,利用mysql中的merge存储引擎来分表查询,查询的时候通过union或者视图查询,针对查询一个周的日期的数据,可以写个脚本针对一周的时间的数据汇总到一张表中查询。

例如:使用merge存储引擎来实现一张完整的code表

CREATE TABLE IF NOT EXISTS `code` (

`full_code` char(10) NOT NULL,

`create_time` int(10) unsigned NOT NULL,

INDEX(full_code)

) TYPE=MERGE UNION=(code_0,code_1,code_2.......) INSERT_METHOD=LAST ;

通过select * from code就可以得到所有的full_code数据了。

  1. mysql的三大搜索引擎是啥?

InnoDB (默认):适合高并发,支持事务回滚机制,数据和索引文件占用磁盘空间,处理效率没有myisam高。

MyISAM:不适合高并发处理,事务机制支持比较差,优点数据文件和索引文件可以放置在不同的目录,访问数据比较快。

MEMORY:数据存在内存中,访问速度快,但是服务器宕机,数据就没有了。

MERGE:一组数数据表的组合查询的,本身表没有数据的,且数据表类型必须是MyISAM的类型,且表结构要一致。

  1. mysql实现读写分离的方式?

有两种方式:a.程序代码 b.中间件(amoeba,mysql-proxy,mycat)

 

1 程序修改mysql操作类

可以参考PHP实现的Mysql读写分离,阿权开始的本项目,以php程序解决此需求,主要通过程序来做读写匹配操作(select/insert/update/delete)

优点:直接和数据库通信,简单快捷的读写分离和随机的方式实现的负载均衡,权限独立分配

缺点:自己维护更新,增减服务器在代码处理

 

2 amoeba (阿里巴巴现在用的就是这个,推荐使用)

参考官网:http://amoeba.meidusa.com/

优点:直接实现读写分离和负载均衡,不用修改代码,有很灵活的数据解决方案

缺点:自己分配账户,和后端数据库权限管理独立,权限处理不够灵活

 

3 mysql-proxy (这个是一个mysql的中间件,这个不建议使用)

参考 mysql-proxy。

优点:直接实现读写分离和负载均衡,不用修改代码,master和slave用一样的帐号

缺点:字符集问题,lua语言编程,还只是alpha版本,时间消耗有点高

 

4.mycat 中间件来实现读写分离

 

  1. mysql索引如何存储?

b-tree ,hash

  1. 大数据量的数据库,如何优化读写性能?

可以采取分区分库,写的设置为主数据,读可以设置为从数据,数据之间通过二进制文件来达到数据同步机制,其次添加索引来优化数据查询速度,索引在数据量多的表中可以体现出查询的性能,但索引设置这块要注意,要经常查询的字段上设置,单索引,双索引。

注意:数据库主从分离如何同步数据:主数据库master会记录操作日志、从数据库会把读取二进制日志记录操作同步到从服务器上面,进行操作。

  • mongdb数据:

MongoDB是一个基于分布式文件存储的数据库

​ 缓存层问题汇总

redis

  1. redis持久化有几种?

RDB,AOF这两种 、两种的区别?

RDB:指定的时间间隔内将内存中的数据集快照写入磁盘。

AOF:以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录

  1. redis 集群模式有几种?

主从复制:master会同步数据快照命令给slave从节点,slave执行快照命令达到数据同步机制。

集群:直接在集群的节点上面配置要绑定的数据库ip地址即可,打开配置cluster-enable.

哨兵:作用是监控 redis系统的运行状况,

  • 监控主从数据库是否正常运行
  • master出现故障时,自动将slave转化为master:通过选举从节点来进行投票,一般以发现master故障的领头的哨兵为主节点,也可以通过投票选取,如果参与投票超过一半领头哨兵,那就选取最小的哨兵来作为主节点,替换故障旧的master的到数据库中。
  • 多哨兵配置的时候,哨兵之间也会自动监控
  • 多个哨兵可以监控同一个redis

 

redis集群各节点之间通过tcp连接发送ping消息来达到通信机制,接受者以pong回复。

  1. redis提供了6种内存淘汰策略?

其中默认的策略为noeviction策略

· noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。

· allkeys-lru:在主键空间中,优先移除最近未使用的key。(推荐)

· volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。

· allkeys-random:在主键空间中,随机移除某个key。

· volatile-random:在设置了过期时间的键空间中,随机移除某个key。

· volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。

通过配置redis.conf中的maxmemory这个值来开启内存淘汰功能

 

  1. redis消息队列

主要使用List结构使用push(存)和pop(取),redis的性能还是比较好,最主要可以分布式部署,百万级别的日活量还是没问题的。

 

redis 分布式锁通过set(设置锁)和eval(解锁)

memcache

常用语法:set、add、replace

分布式缓存服务器,一般通过路由的形式来代理做,基本架构,memcached+magent,magent主要是缓存代理

 

redis、memcached、MongDB区别:

1.redis,memcache都是把数据存放在内存中。

2.redis,memchach都是用来存储缓存数据,比较多一点,

memcanche一般缓存session数据也可以用来存储视频图片等,读的比较多,

而redis主要用来做数据读写操作较多,redis可以做到数据持久化存到磁盘上去

1.性能方面:

redis、memcached 的tps差不多,不过都大于mongdb

2.操作方面:

memcache数据结构单一,通过hash来存储的

redis丰富一些,数据操作方面提供了String,list,set,hash存储数据方式。

mongdb跟关系数据很类似,提供了表达式查询等

3.内存和空间方面:

redis:主要存储在内存上面,可以通过设置过期 淘汰机制来降低自身的VM。

memcanche:可以修改最大内存,

mongdb:适合大数据存储,不过吃内存比较厉害。

4.数据存储方面:

redis:支持数据持久化更安全一点。

memcanche:不支持持久化。通常用作缓存,断电就会挂掉

mongdb:可以持久化

 

 

​ 消息组件问题汇总

kafak

 

是一个开源的发布-订阅的消息中间件,由producer、broker、consumer、zookeeper这几大构件组成。Kafka主要特点是基于Pull的模式来处理消息-消费,追求高吞吐量 创建topic消息,然后消费者去获取消息,好处:高吞吐量,可以备份日志。kafka它主要用于处理活跃的流式数据,大数据量的数据处理上。常用日志采集,数据采集上。

kafka主要和Zookeeper搭配使用

  1. kafka部署模式?

1)单broker模式

2)单机多broker模式 (伪集群)

3)多机多broker模式 (真正的集群模式)

zookeeper.properties中配置端口号、server.properties中

 

rabbitMQ

 

  1. rabbitMQ优势

1,分布式系统下可以异步、负载均衡一些列高级功能、

2,拥有持久化机制,可以保存进程消息和队列中的信息。

3,对高并发情况下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,有利于数据库操作。

4、对使用消息队列达到异步下单效果,排队中,后台进行逻辑下单。

 

总结rabbitMQ好处:异步处理、消息缓冲、消息分发,应用解耦,削峰等。

 

mq缺点:

系统可用性降低,系统复杂性提高,数据一致性问题难以解决。

 

  1. rabbtiMQ有6种模式

 

简单模式:一个生产者,一个消费者。

 

work模式:一个生产者,多个消费者,每个消费者获取到的消息唯一。

 

订阅模式:一个生产者发送的消息会被多个消费者获取。

 

路由模式(推荐):发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key

 

topic模式:将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。

 

 

交换机模式(路由模式):

Java 面试问题汇总_第3张图片

 

原理:通过客户端发送消息经过Routing key 到Exchange,通过exchange发送到对应的queue队列中,接受消息的就会从队列中获取消息。

 

其中:exchange(交换空间)主要用于把消息队列发送到指定的队列中去,就是通过bingingKey 来链接exchange和queue。但是如何发送到指定的队列了,就是exchange中有四种类型:

(fanout(消息广播所有的队列)/direct(推荐,通过对应的Routing-key绑定到指定的消息队列中的Key)/topic(通过*匹配进行发送)/headers(根据应用特定消息的匹配))通过这几种类型来转换发送到指定的队列中去。

fanout 最快的

 

以上就是消息路由的过程:通过exchange(交换器),路由、绑定。

 

主题模式和消息队列模式:

主题模式,N多个接受者都可以接受相同的消息,a:123,b:123

队列模式:接受者N个消息接受者接受的不重复如:a:1,3,5,b:2,4,6.

 

如何确保消息被发送到mq中?如何确保消息被接收方消费了?

  1. 发送方确认模式
  2. 接收方确认机制

特殊情况:a、接受者收到消息确认之前,断开了链接,mq会认为没有消费成功,会重复发送的这种情况下要去重。

b、接受者收到消息后,没有确认消息,mq认为消费者比较繁忙,将不会给消费者发送更多的消息。

 

  1. rabbitMQ集群部署

 

RabbitMQ集群中节点包括内存节点(RAM)、磁盘节点(Disk,消息持久化),集群中至少有一个Disk节点。

 

集群部署分为两种模式:

 

普通模式:

对于普通模式,集群中各节点有相同的队列结构,但消息只会存在于集群中的一个节点。对于消费者来说,若消息进入A节点的Queue中,当从B节点拉取时,RabbitMQ会将消息从A中取出,并经过B发送给消费者。

镜像模式:消息实体会主动在镜像节点间同步,而不是在取数据时临时拉取,高可用;该模式下,mirror queue有一套选举算法,即1个master、n个slaver,生产者、消费者的请求都会转至master。如:下单,库存队列。镜像容易产生重复消息。

  1. rabbitMQ和Kafka区别

优势:

Mq:系统异步处理,消息分发,负载均衡,削峰等。

Kafka: 高吞吐量、系统性能高,比较稳定,易于解决分布式架构的大数据高并发请求,适合大数据实时计算和日志采集。

 

缺点

MQ:扩展性差,复杂度高,对系统支撑有风险,不利于维护。源码比较难读懂(erlang语言开发的)

Kafka:存在消息被重复消费。

 

​ 负载均衡问题汇总

Nginx

  1. nginx有几种策略

1.轮询(默认)、2.权重、3.ip、4.最少链接方式、5.url、6.响应时间(后面两种是第三方)

  1. nginx分布式集群部署的架构图

Java 面试问题汇总_第4张图片

  1. 两步路tbl架构

客户端发送一个url请求,该请求已经绑定到了阿里云平台的SLB,SLB做了负载均衡,会把请求转发到我们服务器的Nginx上面、Nginx转发请求到我们分布式集群的应用上面,应用在到redis缓存层,最后redis到DB,我们底层的DB也是用的阿里云数据库,采取了读写分离(主从数据库)

Java 面试问题汇总_第5张图片

Java 面试问题汇总_第6张图片

Java 面试问题汇总_第7张图片

 

 

​ 分布式锁问题汇总

  1. zookeeper

一个分布式协调应用服务开源框架, Zookeeper主要实现分布式锁,让进程之间保持有序的访问资源, 保证分布式集群应用的稳定性和可用性.

分布式锁实现技术有:zookeeper和 chubby

 

它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

当集群分布式处理服务请求时,为了保证服务之间可以有序的进行通讯,这个时候通常要采取第三方组件,叫“分布式协调服务”Zookeeper,可以把应用之间的进程有序的进行协调。

 

原理:Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。

 

应用场景:

集群部署的Master选举,如果出现单点故障就会使用到zookeeper,集群选举是这样子,当在集群部署环境下,采用的master和从节点链接,突然master出现问题,就会使用一个备用的替换上去来维持环境正常运行,在这种状态下,主的发送了一个消息通知从,让从的知道主的还活着,从就不会自动启动来替换住,但是存在网络不稳定的状态,主的还是活的,发了一个通知给从的,从的没有收到,就会启动这样子,程序就会乱了,所以这个时候就用到上面提到的zookeeper

Java 面试问题汇总_第8张图片​​Java 面试问题汇总_第9张图片

 

zk 如何保证事务顺序一致性:zk中会产生zxid标识的。

zk如何选取leader的:当leader失去大多数follower就进入zk恢复模式。

zk选举过程:leader崩溃了,zk进入恢复模式

  1. 选举由当前server线程发起,进行投票结果统计。
  2. 向所有的server发起询问。
  3. 选举线程收到回复后,验证自己的zxid并存储到询问对象投票记录表中
  4. 收到所有的server的回复后,计算那个zxid最大,然后推荐为主leader了。如果没有继续上面的过程

 

zk主要通过watch监听各个节点之间的状态,当节点目录改变时,监听会向客户端发送通知消息

改变配置。

zk集群服务器之间如何通信:leader主服务器和每一个follower服务器通过tcp连接,同时为每个F/O创建一个learnerHander实体,这个实体主要负责主服务器和每个F/O之间的网络通讯。

zk日志会自动清理吗?不会,需要运维去清理。

 

zk集群部署中如何做更新:通过配置管理、把应用配置放置zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。

 

 

 

  1. 基于缓存(memcache/redis 推荐使用redis)

set和eval来设置和释放分布式锁,通过过期时间。

  1. 基于数据库

创建一个表,用于存储请求的方法名字,并且设置唯一主键索引,当多个线程请求方法时,会向数据库插入一条数据,因为设置了唯一所以只能插入一条数据,即可获得锁,用完了就可以delete,但是要设置一个过期时间列来保证锁在规定时间可以释放,这时候也要一个定时任务去扫描判断。

 

 

两步路商城用的就是redis分布式锁,来处理防刷单的,可以看我的csdn中的博客文章。

 

分布式锁必须满足:一致性、可用性和分区容错性。

​ 大数据问题汇总

  • 仅批量框架:
  • Apache Hadoop: 是一种专用于批处理的处理框架

1. HDFS(Hadoop Distributed File System)是一种分布式文件系统层,可对集群节点间的存储和复制进行协调

Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,

优势:可以运行于廉价的商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集(LargeData Set)的应用处理带来了很多便利。

系统:HBase是一种构建在HDFS之上的分布式、面向列的存储系统。在需要实时读写、随机访问超大规模数据集时,可以使用HBase。

HDFS的优缺点比较

HDFS 的优点:

1.高容错性 2.适合批处理 3.适合大数据处理(可以处理GB,TB,PB级别的数据)

4.流式文件访问 5.构建廉价机器上

HDFS 缺点:

1. 不适合对处理时间有要求较高的场合(毫秒级存储)

2不适合小文件存储

3. 并发写入、文件随机修改

仅流式框架:

  • 混合框架:

Apache Storm: 是一种侧重于极低延迟的流处理框架,也是要求近实时处理的工作负载的最佳选择框架、目前来说Storm可能是近实时处理领域的最佳解决方案。

优点:比较适合处理流数据,可配合多种语言使用,低延时性强。

缺点:不支持批处理,如果要保证一次较高的要求需要配合其他trident使用,默认配置可能产生重复结果并且无法保证顺序。

• ApacheSamza: 一种与Apache Kafka消息系统紧密绑定的流处理框架。

优点:低延时工作负载比较好

缺点:目前Samza只支持JVM语言,这意味着它在语言支持方面不如Storm灵活。

ApacheSpark:是一种包含流处理能力的下一代批处理框架。

批处理模式:使用rdd写入到内存中进行批处理,也可以容错

流处理模式:spark本身设计面向批处理工作负载的,使用了微批概念,主要以缓冲作为小规模数据在内存中批处理,不过这种方式效果没有真正流处理框架的性能好。

Spark的另一个重要优势在于多样性。该产品可作为独立集群部署,或与现有Hadoop集群集成。该产品可运行批处理和流处理,运行一个集群即可处理不同类型的任务。

缺点:就是占用内存的使用率,特别是集群部署或者和hadoop集群部署是,会出现出现资源不足的情况,这时候就要优化资源,或者通过jvm调优,扩展内存

ApacheFlink:是一种可以处理批处理任务的流处理框架

缺点:目前使用的还不够成熟。

优点:可以自行管理各个组件,优化性能,不需要靠java垃圾回收机制,

可以实现数据“增量跌点”

 

 

​ 其他技术点

RPC

远程过程调用,通过网络计算机程序进程来调用的一种服务、主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性

RPC调用分类:

同步调用/异步调用、区别:同步调用会返回调用接口,异步不用等待返回接口

原理:rpc通过服务端rpcServer导出调用的方法,rpcClient客户端导入服务端的方法,调用本地方法一样调用使用,主要通过rpc proxy 代理接口来实现,通过rpc invoke 执行 RpcConnector 链接 链接过程中编码信息发送给服务端,服务端将消息解码最后委托给rpc invoke 返回给客户端。

RPC组件:比如Java RMI、WebService的RPC风格、Hession、Thrift、REST API

docker容器技术

是一种集装箱,可以运行在Linux系统中,把所有的应用程序,打包运行在自己的容器中的,docker通过虚拟机来运行各自的应用,互不干扰。

优点:资源利用率高、可以有效隔离物理机,互不干扰、运维部署方便、快速,迁移成本低,

持续集成、版本控制、可移植性、隔离性和安全性。

ELK技术

EKL分别是:elasticsearch(搜索引擎)、kibana(网页现实的搜索页面)、logstash(收集日志的插件). 主要用来监控服务器端各种设备或软件产生的日志,做具体分析。

一般我们收集Nginx服务器端的日志,让logstash去收集服务段日志,elasticsearch负责搜索查询日志、kibana页面提供展示,让用户可以在页面上面进行输入查询操作。

 

elasticsearch技术:一个分布式搜索引擎分析框架,最大的优势就是可以通过建立索引机制来实时查询数据,现在很多公司做的搜索引擎都是用这个框架。

特点:全文检索、结构化检索、数据统计、接近实时处理,分布式搜索,处理PB级别的数据。

使用场景:服务器日志搜索,数据聚合、数据监控,报表统计分析。

k8s

是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非常的方便,而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之,让apache一直提供服务),管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提升工具以及人性化方面,让用户能够方便的部署自己的应用(就像canary deployments)。

在这边可以看到k8s在物理上进行划分的时候,划分了两种类型的主机,一个master节点,主要用来调度,控制集群的资源等功能;而node节点,主要是用来运行容器的节点,也就是运行服务的节点。

 

​ web前端问题汇总

跨域请求方式:

jsonp 可以在js端实现、window.name方式、

H5中的window.postMessage来跨域,post提交,代理都可以

 

前后端分离技术:

vue.js框架使用

note.js

前后端分离api文档服务器用什么做的?

 

 

 

面试题:

面试题1:如何控制一个报名100人的活动,不会超过100人。

解决思路:涉及到两个点,分布式锁和消息队列,分布式锁就是高并发请求的线程数,要锁住当前线程请求的操作,消息队列主要用来控制多个请求的顺序。

实现方法多种如下:

  1. 通过java多线程同步机制来实现,在方法中使用synchronization,让线程按照队列的形式访问.
  2. 使用java中的volatile关键字来实现变量共享机制,在方法调用的时候如果变量超过100终端线程,停止报名。
  3. 通过第三方消息组件队列来控制,kafaka/rabbitmq/redis
  4. 通过redis中的消息队列:list中的push和pop来实现。
  5. 或者用zookeeper来实现分布式锁的控制

 

 

设计一个高并发请求的秒杀活动,如何设计?跟上面的100人报名一样的(这是网上的解决方案)

秒杀主要考虑的是限流,降低服务器在某个时间点的压力。设计如下:

  1. 请求端:采用网管或者路由控制请求高并发,负载均衡,阿里云有个SLB 绑定了域名对应的ip地址。
  2. 服务端:
  1. 采用异步消息队列(redis,rabbitmq,kafka)组件来控制请求数,让多个请求保持在队列中有序的进行,后台数据库订阅消息减库存,可以降低在某个时间点请求给后端增加压力,用消息队列直接拦截掉请求数,如果是100个,就没必要让超过一百个请求数进入后台了。
  2. 使用缓存(redis)来提高系统读写速度,主要缓存数据库中的库存数,所以库存下单都是在缓存中进行,然后在通过redis同步到数据库中。

 

  1. 数据库:数据库层是最脆弱的一层,一般在应用设计时在上游就需要把请求拦截掉,数据库层只承担“能力范围内”的访问请求。所以,上面通过在服务层引入队列和缓存,让最底层的数据库高枕无忧。

 

面试题2:高并发请求下,如何控制redis和数据库数据一致性问题?

1.采用延时双删策略:设置缓存过期时间,来达到数据同步一致性问题,不过超时高并发请求会存在数据不一致性(不推荐)

2.异步更新缓存(基于订阅binlog的同步机制)策略来保持一致性(推荐使用)

过程:读取binlog(二进制日志)文件,利用消息组件(rabbitMQ、kafka)推送到各台Redis上,Redis再根据binlog进行同步操作,其实这里跟mysql主从数据同步原理一样,都是通过二进制日志文件来同步数据的。

针对商城订单高并发处理的方案,自己总结的,面试可以随便回答一下

Java 面试问题汇总_第10张图片

请求层:可以使用Nginx来解决高并发负载均衡,提高系统带宽,增加吞吐量。我们系统用的是阿里云绑定域名 叫SLB,也可以通过路由形式来处理。

 

服务层:我们使用异步消息队列组件(redis/rabbit/kafka)来保证多线程请求下,在队列中有序的进行。这里我们使用了redis中的list来做的消息队列。

访问数据这块我们可以使用缓存机制,采用redis集群分布式部署策略:主从,把库里面的订单数据直接放入到缓存中,直接通过消息队列来读取缓存下单,最后同步到数据库中。

 

数据层:如果是大数据的话,我们可以针对数据库做些读写分离优化处理,数据库可以分区分表、同时设置索引来优化数据库性能,优化sql语句等操作

 

注意:这里我们做了一个防刷单的处理,通过spring AOP面向切面形式写的一个针对参数请求的方法来判断,使用参数的hashcode来的比对,然后在使用了redis中的对象锁设置过期时间来控制防刷操作。

如何在10亿条随机数中获取10个最大的随机数?

这个涉及到大数据算法:堆排序(创建大顶堆和小顶堆)、快速排序。

Java 实现分布式锁的方法?

数据库乐观锁(version版本号来控制)、redis/zookeeper(这两种最常用)/ memcache

面试题3:高并发请求下,如何控制防刷单问题?

  1. 可以通过前台和后台做验证码效验(比较低级,不建议,黑客写个脚本就可以破解了)
  2. 增加同一IP指定时间范围内访问次数
  3. redis中可以设置过期时间来控制ip地址在同一个时间段内请求次数。
  4. 可以使用spring中的AOP来扫描注解,过滤每次请求的参数(通过hashcode判断),结合第三步redis设置过期时间控制。
  1. 面试题 spring IOC原理:主要反射机制来实现的(动态和静态)。AOP:分为静态代理(运行时命令)和动态代理(借助jdk来完成),主要做些安全认证,事务控制,缓存等操作,单独代码切入到应用程序中,剥离了应用程序,主要通过IOC代理来实现。其编程思想是把散布于不同业务但功能相同的代码从业务逻辑中抽取出来,封装成独立的模块,这些独立的模块被称为切面,切面的具体功能方法被称为关注点。在业务逻辑执行过程中,AOP会把分离出来的切面和关注点动态切入到业务流程中,这样做的好处是提高了功能代码的重用性和可维护性

反射的优点:在java运行时才进行动态加载,比较灵活,方便程序代码解耦。

反射的缺点:影响性能。

反射一般通过工厂模式来取得反射的实例。

  1. 面试题:spring cloud中服务注册中心中的的很多服务不稳定或者挂了,如何处理?

容器中有个hystrix 断路器,许多依赖不可避免调用失败,超时,异常,hystrix能够保证一 个依赖出现问题下,不会导致整个服务失败,避免级联故障,提高分布式系统弹性。

还有个自我保护机制可以开启他,如果网络发现不稳定或者停止,eureka在90秒没有检测到心跳,就可以剔除掉,让新的服务注册进来。

默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。

自我保护机制:

1、Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。

2、Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上, 保证当前节点依然可用。

3、当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。

Java 面试问题汇总_第11张图片

  1. spring cloud 如果服务注册中心挂了怎么办,服务就用不起来了如何处理?

注册中心会有配置多个属性文件里面配置了多个端口号,如果其中一个挂了另一个会继续提供服务,会通过心跳来检测服务是否还存在,自我保护机制吧。

Java 面试问题汇总_第12张图片

  1. kafka如何保证消息有序性?

可以建立多个queue,具有相同的key hash数据存到同一个内存中的queue中,N多个线程就可以分别访问不同的内存就可以了,其实跟rabbitMq中的交换机模式很像通过路由绑定key到指定的队列中去。

Java 面试问题汇总_第13张图片

  1. spring 中的安全如何控制?

Apache的shiro、Spring Security。

使用spring security 和spring-security-oauth2 来实现用户授权,用户认证

如何保证微信支付安全性?

我们可以设置用户认证,数据加密,数据库采用事务机制来控制。

 

  1. spring 中的controller默认是单例模式的
  2. restful风格,统一的URL,对应的get、post,put、delete、PATCH
  3. Java 面试问题汇总_第14张图片
  4. mysql索引如何存储? b-tree ,hash

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

- 工作总结模板 -

你可能感兴趣的:(技术类,java,web技术类)