面试题(杭州)

本文档汇总了杭州马面试题及多家公司的面试要点,涵盖了集合、多线程、框架原理、数据库优化等内容,深入剖析了HashMap的底层原理、线程安全问题、Spring框架的IOC与AOP实现等核心技术。

文章目录

杭州马面试题

1.常见的集合有哪些?都有什么区别:

List集合:
ArrayList:数组结构,线程不安全,执行查询效率块,增删改慢
LinkList:链表结构,对元素执行增删改效率高
Set集合:
HashSet:要保证元素唯一性,需要覆盖掉Object中的equals和hashCode方法
(因为底层是通过这两个方法来判断两个元素是否是同一个)
TreeSet:以二叉树的结构对元素进行存储,可以对元素进行排序
Map集合:元素是成对出现的,以健值对的方式体现,健保证唯一性
HashMap:线程不安全,允许存放null键null值
HashTable:线程安全,不允许存放null键null值
TreeMap:可以对键进行排序,

2.HashMap的底层原理:

是以数组和链表的形式存储元素

3.sleep和wait的区别

  1. wait来自Object类,sleep来之Thread类
  2. 调用sleep方法,线程不会释放对象锁,而调用wait方法线程会释放对象锁
  3. sleep睡眠后不出让系统资源,wait让其他线程可以占用cup
  4. sleep需要一个指定睡眠时间,时间一到会自动唤醒,而wait需要配合notify方法或者notifyAll方法使用

4.run方法和start方法的区别:

run方法:当前普通方法的方式调用,程序还是顺序执行,还是要等待run方法体执行完毕后才会继续执行下面的代码

start方法:用来启动线程,真正实现了多线程运行,无序等待run方法体执行完毕后才执行下面的代码

5.Threadlocad的作用:

提供线程内部的局部变量,并且这些变量依靠线程独立存在,可以在多个线程中互不干扰的进行存储数据和修改数据,通过set,get和remove方法。每个线程都是独立操作

原理:在不同的线程中访问一个对象,获取的值是不一样的,因为内部会从各个线程取出一个数组,
	  通多对应的下标,查找对应的值

6.solr查询出的数据放在哪:

本地 磁盘中

8.支付宝的支付流程:

先是生成商户系统一笔未支付的订单,获得商户订单ID(商户系统生成)和订单的一些其他信息,然后再调用支付宝的SDK提供的数字签名方法,将需要传给支付宝的信息进行加签,然后把加签后的字符串返回给APP。APP拉起支付宝APP,再把这个加签的字符串传给支付宝,完成支付。APP接收到同步通知后,还需要再次调用商户后台的接口(虽然同步通知也有付款情况,但需要以后台通知为准),校验订单最终的付款情况。按照支付宝API上所说,当完成支付后,支付宝会做2个操作,一个是同步返回信息给APP,一个是异步通知商户后台返回支付状态等信息,并且最终的支付结果是以异步通知为准。所以我们还需要考虑到一点,就是当用户支付成功之后,商户系统暂时没有接收到支付宝的异步通知时。我们需要拿着这个商户订单ID主动调用SDK支付宝的查询接口,去获取该订单的支付情况,并最终返回给APP

当点击支付的时候将一笔未支付的订单信息(包含商家,商品以及用户的信息)给支付宝,当输入支付密码支付宝调用SDK加签再给支付宝,当支付完成后,支付宝会做2个操作,一个是同步返回信息给APP,一个是异步通知商户后台返回支付状态等信息,并且最终的支付结果是以异步通知为准

11线程池工作原理:

先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态

22.Hashmap的底层原理?

HashMap底层是通过数组加链表的结构来实现的HashMap 的实例有两个参数影响其性能
:“初始容量” 和 “加载因子”HashMap 根据键的 hashCode 值存储数据,大多数情况
下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。
HashMap 最多只允许一条记录的键为 null ,允许多条记录的值为 null 。
HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会
导致数据的不一致。如果需要满足线程安全,可以用 Collections的
synchronizedMap 方法使 HashMap 具有线程安全的能力,或者使用ConcurrentHashMap。
在JDK1.8之前,它的底层结构是数组+链表,而在JDK1.8之后,为了查询效率的优化
(主要是当哈希碰撞较多的时候),它的底层结构变成了数组+链表+红黑树

23.有对hashmap初始容量进行修改过吗?修改原理初始容量?

当我们设置了初始化容量,HashMap就会按照我们设置的容量进行设置吗?
答案是不一定。当你设置的初始化容量是2的n次方时,就会按照你设置的容量设置
;当你设置的初始化容量不是2的n次方时,就会按照大于你设置的那个值但是最接近
你设置的那个值的2的n次方进行设置其中size是HashMap中添加键值对的数量,
而threshold是容量加载因子(capacity * load factor)得出的值,
也是就当我们的容量是16,加载因子是0.75时,当键值对的数量大于160.75=12时
,HashMap会进行扩容操作

24.多线程中使用的集合有哪些是线程安全的?

ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合
ConcurrentSkipListSet是线程安全的有序的集合,适用于高并发的场景
LinkedBlockingQueue是一个线程安全的阻塞队列,它实现了BlockingQueue接口
,BlockingQueue接口继承自java.util.Queue接口,并在这个接口的基础上增加了
take和put方法,这两个方法正是队列操作的阻塞版本。
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,
其中所有可变操作(add、set等等)都是通过对底层数组进行一次新的复制来实现的
Vector和HashTable实现了线程安全的数组和散列表;在java1.2版本中他们就已经不再使用了
,取而代之是ArrayList和HashMap这些集合类不是线程安全但是他们可以通过集合库中提供的
同步包装器使其变成线程安全的;

28.线程的生命周期?

New(初始化状态)
Runnable(可运行/运行状态)
Blocked(阻塞状态)
Waiting(无时间限制的等待状态)
Timed_Waiting(有时间限制的等待状态)
Terminated(终止状态)
1.New(初始化状态):指的是在高级语言,比如Java。在Java层面的线程被创建了,而在操作系统中的
线程其实是还没被创建的,所以这个时候是不可能分配CPU执行这个线程的!所以这个状态是高级语言独
有的,操作系统的线程没这个状态。我们New了一个线程,那时候它就是这个状态。
2.Runnable(可运行/运行状态):这个状态下是可以分配CPU执行的,在New状态时候我们调用start()方法后线程就处于这个状态。
3.Blocked(阻塞状态):这个状态下是不能分配CPU执行的,只有一种情况会导致线程阻塞,就是synchronized
!我们知道被synchronized修饰的方法或者代码块同一时刻只能有一个线程执行,而其他竞争锁的线程就从
Runnable到了Blocked状态!当某个线程竞争到锁了它就变成了Runnable状态。注意并发包中的Lock,是
会让线程属于等待状态而不是阻塞,只有synchronized是阻塞。(感觉是历史遗留问题,没必要多一个阻塞状态和等待没差啊)。
4.Waiting(无时间限制的等待状态):这个状态下也是不能分配CPU执行的。有三种情况会使得Runnable状态到waiting状态
调用无参的Object.wait()方法。等到notifyAll()或者notify()唤醒就会回到Runnable状态。
调用无参的Thread.join()方法。也就是比如你在主线程里面建立了一个线程A,调用A.join(),那么你的主线程是得等A执行完了才会继续执行,这是你的主线程就是等待状态。
调用LockSupport.park()方法。LockSupport是Java6引入的一个工具类Java并发包中的锁都是基于它实现的,再调用LocakSupport.unpark(Thread thread),就会回到Runnable状态。
5.Timed_Waiting(有时间限制的等待状态):其实这个状态和Waiting就是有没有超时时间的差别,这个状态下也是不能分配CPU执行的。有五种情况会使得Runnable状态到waiting状态
Object.wait(long timeout)。
Thread.join(long millis)。
Thread.sleep(long millis)。注意 Thread.sleep(long millis, int nanos) 内部调用的其实也是Thread.sleep(long millis)。
LockSupport.parkNanos(Object blocked,long deadline)。
LockSupport.parkUntil(long deadline)。
6.Terminated(终止状态):在我们的线程正常run结束之后或者run一半异常了就是终止状态!
注意有个方法Thread.stop()是让线程终止的,但是这个方法已经被废弃了,不推荐使用,因为比如你这个线程得到了锁,你stop了之后这个锁也随着没了,其它线程就都拿不到这个锁了!这不玩完了么!所以推荐使用interrupt()方法。
interrupt()会使得线程Waiting和Timed_Waiting状态的线程抛出 interruptedException异常,使得Runnabled状态的线程如果是在I/O操作会抛出其它异常。
如果Runnabled状态的线程没有阻塞在I/O状态的话,那只能主动检测自己是不是被中断了,使用isInterrupted()。

29.说下Ioc Aop 和项目中用到的地方?

ioc,控制反转,这个指的就是我们获取对象的方式进行反转了,改变了。在使用spring之前是需要手
动new出来的,是我们主动获取的。使用spring之后,是将这个获取的过程交给spring来管理,我们只需
要告诉spring你需要什么就行了,它就会把东西给你。比如:在没有电商的时候,我们去上街买东西,需
要考虑到这东西有没有,价钱多少,怎么搬回来,去有多远……等等无数个和主要的业务逻辑(买东西)无
关的问题。这样就会扰乱主业务逻辑。当我们有了电商平台后,买东西时只需要两步。注册账号(装载bean)
,告诉电商你要的东西名字(通过名字获取Bean),然后就可以在门口收到东西了。这就是ioc。
aop,面向切面。在谈这个之前需要了解几个词:切面,切入点,织入,目标对象,通知。
我先解释下名字的意思,再讲故事。
切面:就是你要准备增强的那些方法。
切入点:就是具体织入的方法,定义了地点
织入:动词,就是将切面织入的过层
目标对象:被增强的类
通知:就是什么时候增强,定义了时间
好了,了解清楚上面的几个词的意思后,再听故事就容易多了。
aop的功能就是用来增强,在执行主业务的通知也顺带执行其他业务。如:老李上街办点事儿,走啊走,走到了老王家门前(切入点),老王看见老李问:去哪啊!
老李:上街办点事儿(目标类)
老王:那帮我顺便把这封信投到邮筒里吧。(切面),等到10点的时候邮局开门了去柜台投。(通知)
老李:好嘞。然后老李接过信。(织入)
老李继续走啊走,继续上街办事(增强后的目标类)。办完事后老李回家了。
以上就是aop。aop一般用来处理权限控制,日志记录,加载事务等非主要业务逻辑的事情。底层是采用cglib和jdk的动态代理实现的。

34.项目登录功能实现过程?token怎么生成的?登录是用的框架还是自己直接写的?

获取前端登录的数据(验证码,用户名,密码等),先验证验证码是否正确,再验证用户名和密码(加不加密随意)是否正确,正确与否都要做出提示,然后再设置一个Cookie机制用来保存用户登录的信息,如果勾选了保存密码,就可以对Cookie设置有效期之类的。也可以生成token。 token(分为三部分,header密文,payload密文,签名),将荷载payload,以及Header信息进行Base64加密,形成密文payload密文,header密文,将形成的密文用句号链接起来,用服务端秘钥进行HS256加密,生成签名,将前面的两个密文后面用句号链接签名形成最终的token返回给服务端。 登录用了框架/自己写(视自己的情况说)。

40.Nginx的作用?

一、静态http服务器,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML、图片)通过HTTP协议展现给客户端。二、反向代理服务器,客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端。三、负载均衡,Nginx可以通过反向代理来实现负载均衡。四、虚拟主机,有的网站,由于访问量太小,需要节省成本,将多个网站部署在同一台服务器上。
40微服用户信息如何获取?
用dubbox搭建的微服各模块注册信息从zookeeper注册中心获取,用springcloud搭建的微服各模块注册信息从eureka注册中心获取。

41Sprongboot常用注解?

@Service: 注解在类上,表示这是一个业务层bean
@Controller:注解在类上,表示这是一个控制层bean
@Repository: 注解在类上,表示这是一个数据访问层bean
@Component: 注解在类上,表示通用bean ,value不写默认就是类名首字母小写
@Autowired:按类型注入
@Resource: 按名称装配
@Configuration:注解在类上,表示这是一个IOC容器,
@Bean: 注解在方法上,声明当前方法返回一个Bean
@Scope:注解在类上,描述spring容器如何创建Bean实例。
@Value:注解在变量上,从配置文件中读取。
@ConfigurationProperties: 赋值,将注解转换成对象。
@EnableAutoConfiguration启用 Spring 应用程序上下文的自动配置,试图猜测和配置您可能需要的bean。
@SpringBootApplication=@ComponentScan+@Configuration+@EnableAutoConfiguration:约定优于配置
@ComponentScan:注解在类上,扫描标注了@Controller等注解的类,注册为bean 。
@RestController @RestController 是一个结合了 @ResponseBody 和 @Controller 的注解
@Responsebody:表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping后,返回值通常解析为跳转路径,加上@Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。
@PathVariable、@RequestParam:两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的,区别在于,URL写法不同。
@EnablCaching:pring framework中的注解驱动的缓存管理功能。
@suppresswarnings: 抑制警告
@Modifying :增,改,删加注解

44sleep和wait区别 原理不同

sleep是Thread类的静态方法,是线程用来控制自身流程的,它会使此线程暂停执行指定的时间,而把执行机会让给其他的线程,等到计时时间到,此线程会自动苏醒.
wait是Object类的方法,用于线程间的通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程调用notify方法才醒来,也可以指定时间自己醒来.
 对锁的处理机制不同
由于sleep方法的主要作用是让线程休眠指定一段时间,在时间到时自动恢复,不涉及线程间的通信,因此,调用sleep方法并不会释放掉锁.
但是调用wait方法的时候,线程会释放掉它所占用的锁,从而使线程所在对象中的其他synchronized数据可以被其他线程使用.
 使用的区域不同
由于wait方法的特殊含义,所以它必须放在同步控制方法或者同步语句块中使用,而sleep方法则可以放在任何地方使用.
 异常的捕获
sleep方法必须捕获异常,而wait,notify以及notifyall不需要捕获异常,在sleep的过程中,有可能别其他对象调用其interrupt(),产生InterruptedException异常.
sleep不会释放锁标志,容易导致死锁的发生,所以一般情况下,不推荐使用sleep方法,而是使用wait方法.

52.JDK、JRE、JVM是什么

JDK:Java开发工具包,是整个JAVA开发的核心,包括了JRE,JAVA基本类库和一堆JAVA工具(比如说编译器等等)
JRE:Java运行时环境,包含了JVM和JAVA运行时基本类库
JVM:Java虚拟机,它是Java实现跨平台最核心的部分,所有的java文件被编译成.class文件后,通过JVM进行识别执行

54. IO与NIO的区别

IO是面向流的,NIO是面向缓冲区的:IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方
IO是阻塞的,NIO是不阻塞的:如果在一次读写数据调用时数据还没有准备好,或者目前不可写,那么读写操作就会被阻塞直到数据准备好或目标可写为止。Java NIO则是非阻塞的,每一次数据读写调用都会立即返回,并将目前可读(或可写)的内容写入缓冲区或者从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作。这就好像去超市买东西,如果超市中没有需要的商品或者数量还不够,那么Java IO会一直等直到超市中需要的商品数量足够了就将所有需要的商品带回来,Java NIO则不同,不论超市中有多少需要的商品,它都会立即买下可以买到的所有需要的商品并返回,甚至是没有需要的商品也会立即返回。

55.如何实现多线程

1.继承Thread类,重写run()方法
2.实现Runnable接口并实例化一个线程
3.使用ExecutorService、Callable、Future实现有返回结果的多线程
应用场景: 需要让异步执行的线程在执行完成后返回一个值给当前的线程,当前的线程需要依赖这个值做一些其他的业务操作,这个时候就需要实现有返回结果的多线程

56.如何防止死锁

1.设置加锁顺序
如果一个线程需要锁,那么就需要按照锁的顺序来获得锁
比如说,线程1占据着锁A,,线程2和线程3只有在获取锁A后才能获取到锁B(锁A是锁B的必要条件),所以线程2或3需要等待线程A释放锁之后才可以进行加锁操作
缺点:按照顺序加锁是一个很有效的死锁预防机制,但是按序加锁也就意味着需要清楚所有可能用到的锁以及锁之间的先后顺序
2.设置加锁时长
若一个线程在给定的时间内没有成功的获取到所需要的锁,则会进行回退并释放其所占用的的锁,然后等待一段随机的时间后在进行尝试
缺点:有些线程可能需要花很长时间去执行任务而导致了锁的超时,所以并不能确定一定发生了死锁
3.设置死锁检测
当一个线程获取锁后,会对其进行记录,记录在数据结构中,如果有线程对某锁进行请求,也会进行记录。当一个线程请求锁失败后,这个线程会去遍历锁的关系图,如果发现发生了死锁,线程则会进行回退和等待,当然,也有可能发生回退后大量线程抢占同一批锁的情况,继而又发生了死锁,这里可以对线程设置优先级,让部分线程先进行回退操作

57. 消息队列

1.为什么要用消息队列?
解耦:A系统调用B系统、C系统,传统的调用是直接调用,但是当B系统说我不需要你提供数据了,这时候A需要改代码,C系统说我不需要某个字段了,这时候A也要改代码,如果又多了一个D系统,A又要写代码。为了实现解耦,引入消息队列,A将产生的数据丢到消息队列中,哪个系统需要,哪个系统就去取;
异步:A系统调用B系统,B系统由于某个需要调用第三方接口超时,导致A系统响应速度慢,而B系统的好坏又不会影响业务逻辑,所以可以改为A异步调用B,A将消息丢到消息队列中,B系统订阅消息,实现A的快速响应;
削峰:当大量流量请求到系统A时,由于数据库的处理能力有限,造成数据库连接异常。使用消息队列,大量请求先丢到消息队列中,系统A使用按批拉数据的方式,批量处理数据,生产中,高峰期短暂的消息积压是允许的。
2.使用消息队列有什么缺点
系统复杂性增加:需要考虑消息的处理,包括消息幂等性(重复消费问题),消息保序性(一个订单多条消息问题),以及消息中间件本身的持久化和稳定性可靠性
系统的可用性降低:解耦后,多个系统通过消息中间件交互,消息中间件挂了整个系统就挂了
3.各种MQ的比较
ActiveMQ:
优点: 技术成熟,功能齐全,历史悠久,有大量公司在使用
缺点: 偶尔会有较低概率丢失数据,而且社区已经不怎么维护5.15.X版本
适用场景: 主要用于系统解耦和异步处理,不适用与大数据量吞吐情况。互联网公司很少适用
rabitMQ:
优点: 吞吐量高,功能齐全,管理界面易用,社区活跃,性能极好
缺点: 吞吐量只是万级,erlang难以二次开发和掌控;集群动态扩展非常麻烦
适用场景: 吞吐量不高而要求低延迟,并且不会频繁调整和扩展的场景。非常适合国内中小型互联网公司适用,因为管理界面非常友好,可以在界面进行配置和优化/集群监控
rocketMQ
优点: 支持百千级大规模topic。吞吐量高(十万级,日处理上百亿)。接口易用。,分布式易扩展,阿里支持。java开发易于掌控
缺点: 与阿里(社区)存在绑定。不兼容JMS规范
适用场景: 高吞吐量
Kafka
优点: 超高吞吐量,超高可用性和可靠性,分布式易扩展
缺点: topic支持少,MQ功能简单,消息可能会重复消费影响数据精确度
适用场景: 超高吞吐量场景而数据精确度没那么高,天然适合大数据实时计算和日志采集场景

58. 内存溢出

内存溢出的情形:
1.java堆内存溢出: 当出现java.lang.OutOfMemoryError:Java heap space异常时,就是堆内存溢出了
发生场景:1.设置的jvm内存太小,对象所需内存太大,创建对象时分配空间,就会抛出这个异常。2.流量/数据峰值,应用程序自身的处理存在一定的限额,比如一定数量的用户或一定数量的数据。而当用户数量或数据量突然激增并超过预期的阈值时,那么就会峰值停止前正常运行的操作将停止并触发java . lang.OutOfMemoryError:Java堆空间错误
解决方法:首先,如果代码没有什么问题的情况下,可以适当调整-Xms和-Xmx两个jvm参数,使用压力测试来调整这两个参数达到最优值。其次,尽量避免大的对象的申请,像文件上传,大批量从数据库中获取,这是需要避免的,尽量分块或者分批处理,有助于系统的正常稳定的执行。最后,尽量提高一次请求的执行速度,垃圾回收越早越好,否则,大量的并发来了的时候,再来新的请求就无法分配内存了,就容易造成系统的雪崩
2. 垃圾回收超时内存溢出:
发生场景: 当应用程序耗尽所有可用内存时,GC开销限制超过了错误,而GC多次未能清除它,这时便会引发java.lang.OutOfMemoryError。当JVM花费大量的时间执行GC,而收效甚微,而一旦整个GC的过程超过限制便会触发错误(默认的jvm配置GC的时间超过98%,回收堆内存低于2%)
解决方法:减少对象生命周期,尽量能快速的进行垃圾回收

59 内存溢出的原因和解决方法

原因:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
  2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
  3.代码中存在死循环或循环产生过多重复的对象实体;
  4.使用的第三方软件中的BUG;
  5.启动参数内存值设定的过小;
解决方法:
第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
  第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
  第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

61设计模式以及原理?

1、工厂模式:创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
2、单例模式:创建型模式,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。应用实例:一个班级只有一个班主任。使用场景:1、要求生产唯一序列号。2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等
3、代理模式:结构型模式,在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。应用实例:Windows 里面的快捷方式。使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。
4、MVC模式:Model-View-Controller(模型-视图-控制器)模式,这种模式用于应用程序的分层开发,Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器;View(视图) - 视图代表模型包含的数据的可视化;Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

62、分布式和集群的区别?

多台服务器合起来跑的才是一套完整代码,这就叫分布式;多台服务器跑的都是一套完整的代码,这就叫集群

63微服框架?

微服务架构是一种架构模式或者说是一种架构风格,它将单一应用程序划分一组小的服务,每个服务运行在其独立的自己的进程中,服务之间按照一定的方式进行通信。

66、Jdk 1.8新出了什么功能?

1、default关键字
2、Lambda 表达式
3、函数式接口
4、方法与构造函数引用
5、局部变量限制
6、Date Api更新;
7、流

68、内连接和左外连接的区别?

内连接:显示两个表中有联系的所有数据;左链接:以左表为参照,显示所有数据,右边表数据数据少了补NULL值,数据多了不显示。

69、Zookeeper原理、作用?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。 功能:主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。 原理:Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值