准备笔记

spring IoC 和 DI:

https://blog.csdn.net/bestone0213/article/details/47424255

spring cloud调用服务的方式使用的是RESTful API,dubbo使用的是RPC。

RESTful API基于HTTP请求,性能上低于RPC。但REST相比于RPC更加灵活,不存在代码级别的强依赖,适合快速演化。

RESTful语言无关,而RPC强依赖语言。

业内对微服务的实现,基本是确定一个组织边界,在该边界内,使用RPC; 边界外,使用Restful。这个边界,可以是业务、部门,甚至是全公司。

CAP定理

C——数据一致性,A——服务可用性,P——服务对网络分区故障的容错性

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。

Zookeeper保证的是CP,即任何时刻对。

Spring Cloud Netflix在设计Eureka时遵守的就是AP原则。


在它的实现中,节点之间是相互平等的,部分注册中心的节点挂掉也不会对集群造成影响,即使集群只剩一个节点存活,也可以正常提供发现服务。哪怕是所有的服务注册节点都挂了,Eureka Clients上也会缓存服务调用的信息。这就保证了我们微服务之间的互相调用是足够健壮的。

Eureka Server可以运行多个实例来构建集群,解决单点问题,但不同于ZooKeeper的选举leader的过程,Eureka Server采用的是Peer to Peer对等通信。这是一种去中心化的架构,无master/slave区分,每一个Peer都是对等的。在这种架构中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的serviceUrl指向其他节点。每个节点都可被视为其他节点的副本。

默认配置下,如果Eureka Server在一定时间内没有接收到某个服务实例的心跳,Eureka Server将会注销该实例(默认为90秒,通过eureka.instance.lease-expiration-duration-in-seconds配置)。当Eureka Server节点在短时间内丢失过多的心跳时(比如发生了网络分区故障),那么这个节点就会进入自我保护模式。

什么是自我保护模式?默认配置下,如果Eureka Server每分钟收到心跳续约的数量低于一个阈值(instance的数量*(60/每个instance的心跳间隔秒数)*自我保护系数),就会触发自我保护。在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学前面提到过,那就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。

服务调用端负载均衡——Ribbon

服务调用端熔断——Hystrix

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

在请求失败频率较低的情况下,Hystrix还是会直接把故障返回给客户端。只有当失败次数达到阈值(默认在20秒内失败5次)时,断路器打开并且不进行后续通信,而是直接返回备选响应。

服务调用端代码抽象和封装——Feign

Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。它整合了Ribbon和Hystrix,从而让我们不再需要显式地使用这两个组件。Feign还提供了HTTP请求的模板,通过编写简单的接口和插入注解,我们就可以定义好HTTP请求的参数、格式、地址等信息。接下来,Feign会完全代理HTTP的请求,我们只需要像调用方法一样调用它就可以完成服务请求。


集合相关

http://www.importnew.com/16301.html

Collection和Map,Collection和Map是Java集合框架的根接口

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体(1.8以前)

HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。(1.8以前)

HashMap 是数组 + 链表 + 红黑树(JDK1.8 增加了红黑树部分)实现的。

当链表到达8个元素的时候,自动转换为红黑树结构(1.8以后)

当HashMap中的元素个数超过数组大小loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为16,那么当HashMap中元素个数超过160.75=12的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。


volatile是一个特殊的修饰符,只有成员变量才能使用它。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile变量可以保证下一个读取操作会在前一个写操作之后发生。

如何在两个线程间共享数据?你可以通过共享对象来实现这个目的,或者是使用像阻塞队列这样并发的数据结构

Java中堆和栈有什么不同?

为什么把这个问题归类在多线程和并发面试题里?因为栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈 调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己 的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

wait() 和 sleep()方法有什么不同?

wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。


-------

Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么? 

可以的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用


---

最左前缀,比如 a,b,c  --> a 生效 a,b生效, a,b,c 生效;b,c不生效  。包括or的,都不生效。EXPLAIN 执行计划

前导模糊查询不能利用索引(like '%XX'或者like '%XX%')

短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

----

这个人的博客,有几篇系统的并发博文

https://blog.csdn.net/csujiangyu/article/list/3

闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭着的,没有任何线程可以通过,当到达结束状态时,这扇门才会打开并容许所有线程通过。它可以使一个或多个线程等待一组事件发生。闭锁状态包括一个计数器,初始化为一个正式,正数表示需要等待的事件数量。countDown方法递减计数器,表示一个事件已经发生,而await方法等待计数器到达0,表示等待的事件已经发生。CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行。


闭锁用来等待事件,而栅栏用于等待其他线程.什么意思呢?就是说闭锁用来等待的事件就是countDown事件,只有该countDown事件执行后所有之前在等待的线程才有可能继续执行;而栅栏没有类似countDown事件控制线程的执行,只有线程的await方法能控制等待的线程执行.

ps:闭锁就是比赛大家必须到一个起跑线了,然后开始跑;栅栏就是春游大家开始走,走到休息区,都TM等着,等人齐了,再一起出发去下一个景点


对于ConcurrentHashMap而言,其并发的实现就是通过分段锁的形式来实现高效的并发操作


--------

 Future处理有局限,不重载超时时间的get()方法会一直等待,建议使用重载的get()方法,传入超时时间作为参数。他更大的局限在于

    将两个异步计算合并为一个

    等待Future集合中的所有任务都完成,并返回结果

    仅等待最快的Future完成

猜你喜欢

转载自blog.csdn.net/u012817635/article/details/80414748