1、模块化的好处

那么什么是模块化呢?《 Java 应用架构设计:模块化模式与 OSGi 》一书中对它的定义是:模块化是一种处理复杂系统分解为更好的可管理模块的方式。为什么模块间解耦,复用?
原因:对业务进行模块化拆分后,为了使各业务模块间解耦,因此各个都是独立的模块,它们之间是没有依赖关系。每个模块负责的功能不同,业务逻辑不同,模块间业务解耦。模块功能比较单一,可在多个项目中使用。为什么可单独编译某个模块,提升开发效率?
原因:每个模块实际上也是一个完整的项目,可以进行单独编译,调试为什么可以多团队并行开发,测试?
原因:每个团队负责不同的模块,提升开发,测试效率组件化与模块化
组件化是指以重用化为目的,将一个系统拆分为一个个单独的组件避免重复造轮子,节省开发维护成本;
降低项目复杂性,提升开发效率;
多个团队公用同一个组件,在一定层度上确保了技术方案的统一性。模块化业务分层:由下到上基础组件层:
底层使用的库和封装的一些工具库(libs),比如okhttp,rxjava,rxandroid,glide等
业务组件层:
与业务相关,封装第三方sdk,比如封装后的支付,即时通行等
业务模块层:
按照业务划分模块,比如说IM模块,资讯模块等

2、分布式系统专题

2.1什么是分布式系统?

所谓分布式,无非就是”将一个系统拆分成多个子系统并散布到不同设备“的过程而已。
本质上而言,实现一个分布式系统,最核心的部分无非有两点:
如何拆分——可以有很多方式,核心依据一是业务需求,二是成本限制。这是实践中构建分布式系统时最主要的设计依据。
如何连接——光把系统拆开成 Process 还不够,关键是拆开后的 Process 之间还要能通信,因此涉及通信协议设计的问题,需要考虑的因素很多,好消息是这部分其实成熟方案很多

分布式考察流程:

1、Process(进程)。在分布式系统中,进程是基本单元
2、通信协议。Process 间需要相互配合才能完成工作,因此通信协议是最基本要解决的问题。这部分其实挺复杂,牵涉面光,不过核心还是抓住两方面,一是存在哪些需求,二是各个协议如何满足这些需求
3、命名法。两个 Process 要通信,必须相互知道对方的名字,名字可以是数字,也可以是结构化的字符串。例如众所周知域名系统就是一种命名方案,但是方案还有很多,各有特点
4、协作。上面都在谈 Process 之间的通信,可是为什么要通信?因为要协作。协作是个复杂的主题,其中最基本最基本的一个问题就是同步问题。而聊同步问题必然要聊“锁”……知识点就这么展开了
上面几点是最基础的知识。了解了这些其实就算入门了。可是如何进阶呢?那么必然要开始学习下面的问题:
5、一致性。数据存储时,最基本的问题。其实也是实际设计系统时常常需要反复考虑的问题
6、容错。冗余是容错的基础,但并不是全部,分布式本身为实现容错提供了一些便利,这也是实际设计系统时常常需要考虑的问题

常用的技术实现:

。
Nosql与KV存储(redis,hbase,mongodb,memcached等)
服务化理论(包括服务发现、治理等,zookeeper、etcd、springcloud微服务、)
负载均衡(原理、cdn、一致性hash)
RPC框架(包括整体的一些框架理论,通信的netty,序列化协议thrift,protobuff等)
消息队列(原理、kafka,activeMQ,rocketMQ)
分布式存储系统(GFS、HDFS、fastDFS)、存储模型(skipList、LSM等)
分布式事务、分布式锁等

分布式事务相关问题,答案-》参考该文章

  • 从系统层面考虑,分布式从哪些纬度考虑(天猫)–3次CAP原理和BASE理论**
    一致性,可用性,容错性------其实考察CAP原理。
    基本可用性、软状态、最终一致性-----------BASE理论
  • 分布式一致性协议,二段、三段、TCC,优缺点**
  • 怎么理解强一致性、单调一致性和最终一致性?**
  • 如何保证分布式数据最终一致性?**
  • 什么是著名的拜占庭将军问题?**
  • Raft 算法

2.5、分布式事务(JTA)?分布式事务一致性

实际上与上面所说一致,但是更加详细的步骤JTA的实现。
https://javatar.iteye.com/blog/981787

2.6、什么是一致性hash?,一致性hash(谈一谈一致性哈希算法)和分库分表(什么情景下做分表,什么情景下做分库,数据库分库分表一般数据量多大才需要?)
引申Q:固定Hash算法劣势。
引申Q:一致性Hash算法原理。
引申Q:一致性Hash算法不足以及如何修改。
引申Q:数据节点再增加的情况下,几十万几百万的节点,一致性hash算法如何优化?
参考这篇文章
2.7、最常见的数据分布方式是什么?为了解决数据库服务器的负担,如何做数据库的分布?如何解决业务层的数据访问问题?

其实还是上面说的一致性hash问题,当然还可以有两个角度就是数据范围和数据量分布
参考链接:https://1316478764.iteye.com/blog/2205528

为了解决数据库服务器的负担,如何做数据库的分布?
弹性数据库----逻辑库对应分库分表,之前每张表2000w的数据量的话,则在逻辑分库分为4个分片,每个分片1个表的话,每张表500w数据。如果数据量增长比较快速,则进行水平扩容(水平分库)

如何解决业务层的数据访问问题?
同时对于join,group by等聚合查询复杂查询则不满足。可以利用网关层进行逻辑应用归并处理。

2.8、从分布式系统部署角度考虑,分哪几层?

一、通信,这个任务包括设计适当的网络间进程通信机制,一些样例机制:远程过程调用(RPC)、远程对象调用(ROI)、面向流的通信和面向消息的通信,底层通信机制的实现。
二、进程、设计的问题包括:在客户端服务端的进程和线程管理、代码迁移、软件和代理对象的设计等、
三、命名。为了以透明盒可扩展的方式来定位资源的进程,设计一个易于的名字分配标识符和地址是必不可少的。在移动系统中进行命名带来了进一步挑战,这是由于名字是不能容易绑定到任何静态地地理拓扑上。
四、同步。在进程之间的同步与合作机制是必不可少的。互斥是同步的典型例子,但还需要许多其他形式的同步,如领导者选举。此外,物理时钟的同步,能对所经过时间的本质进行刻画的逻辑时钟,以及全局记录算法,这些都需要不同形式的同步机制。
五、数据存储和访问。数据存储的方式以及所隐含的通过网络对数据的快速和可扩展的访问机制,是影响性能的重要因素。文件系统设计的一些传统问题在分布式系统环境下需要重新考虑。
六、一致性与副本。为了避免出现瓶颈,提供数据的快速访问以及提供可扩展性,对数据对象进行复制是非常必要的。这会导致出现管理副本的问题,以及在分布式环境下维护副本/缓存之间一致性问题。一个简单的例子就是如何取舍数据访问粒度。(大小)
七、容错。容错机制就是在任何连接、节点、进程错误的情况下保持操作正确、高效、弹性过程、可靠的通信、分布式提交、检查点和恢复、协商和共识、故障检测等一定容错的机制。
八、安全。分布式系统的安全包括安全通道、控制访问、密钥管理-生成、分发以及认证。
九、API透明性,易于使用的通信等专业化服务的api对分布式系统服务被非专业用户广泛接受是很重要的。透明性用来隐藏实现策略,避免让使用者卷进细节,可以按照下面方式分类。类似于dubbo中服务暴露的过程。
十、可扩展性和模块化。算法、数据(对象)以及服务必须尽可能地分布。诸如复制、缓存、缓存管理和异步处理等技术能够增加可扩展性。

2.9、分布式全局唯一ID怎样来实现?( 分布式系统的全局id如何实现)

持久型:使用数据库表自增字段或者Sequence生成,为了提高效率,每个应用节点可以缓存一批次的ID,如果机器重启可能会损失一部分ID,但是这并不会产生任何问题
时间型:一般由机器号、业务号、时间、单节点内自增ID组成,由于时间一般精确到秒或者毫秒,因此不需要持久就能保证在分布式系统中全局唯一、粗略递增能特点

2.10、如何实现分布式缓存

http://www.dalbll.com/Group/Topic/ArchitecturedDesign/5205

2.11、分布式锁( 分布式锁的实现你知道的有哪些?具体详细谈一种实现方式)----3次
分布式锁的实现方式你知道有哪些?主流的解决方案是什么?分布式锁的方案,redis和zookeeper哪个个好,如果是集群部署,高并发情况下哪个性能更好。

应用场景:

取任务问题:某服务提供一组任务,A系统请求随机从任务组中获取一个任务;B系统请求随机从任务组中获取一个任务。 在理想的情况下,A从任务组中挑选一个任务,任务组删除该任务,B从剩下的的任务中再挑一个,任务组删除该任务。 同样的,在真实情况下,如果不做任何处理,可能会出现A和B挑中了同一个任务的情况。

引申Q:为什么分布式系统中不能用普通锁呢?那么普通锁和分布式锁有什么区别呢?

普通锁:单一系统中,同一个应用程序是有同一个进程,然后多个线程并发会造成数据安全问题,他们是共享同一块内存的,所以在内存某个地方做标记即可满足需求,例如synchronized和volatile+cas一样对具体的代码做标记,对应的就是在同一块内存区域作了同步的标记。
分布式锁:分布式系统中,最大的区别就是不同系统中的应用程序都是在各自机器上不同的进程中处理的,这里的线程不安全可以理解为多进程造成的数据安全问题,他们不会共享同一台机器的同一块内存区域,因此需要将标记存储在所有进程都能看到的地方。例如zookeeper作分布式锁,就是将锁标记存储在多个进程共同看到的地方,redis作分布式锁,是将其标记公共内存,而不是某个进程分配的区域。

正式回答

分布式锁实现方案主要有三种,zookeeper使用的最多。
zookeeper实现分布式锁方式:
实现方式:
方案1:利用节点名称的唯一性来实现共享锁。
算法思路: 利用名称唯一性,加锁操作时,只需要所有客户端一起创建/test/Lock节点,只有一个创建成功,成功者获得锁。解锁时,只需删除/test/Lock节点,其余客户端再次进入竞争创建节点,直到所有客户端都获得锁。
方案2:利用临时顺序节点实现共享锁。(主要是用这种方式实现)
算法思路:对于加锁操作,可以让所有客户端都去/lock目录下创建临时顺序节点,如果创建的客户端发现自身创建节点序列号是/lock/目录下最小的节点,则获得锁。否则,监视比自己创建节点的序列号小的节点(比自己创建的节点小的最大节点),进入等待。
比如创建节点:/lock/0000000001、/lock/0000000002、/lock/0000000003。则节点/lock/0000000001会先获得锁,因为zk上的节点是有序的,且都是最小的节点先获得锁。
注:临时顺序节点比持久顺序节点的好处是:当zookeeper宕机后,临时顺序节点会自动删除,获取锁的客户端会释放锁,不会一直造成锁等待,而持久节点会造成锁等待。
两种方式的区别:
方案1会产生惊群效应:假如许多客户端在等待一把锁,当锁释放时候所有客户端都被唤醒,然后竞争分布式锁,仅仅有一个客户端得到锁。
方案2是按照创建顺序排队的实现,多个客户端共同等待锁,当锁释放时只有一个客户端会被唤醒,在zk上注册节点最小的客户端会被唤醒,避免了惊群效应。
redis实现分布式锁(用的次之)
redis实现分布式锁主要靠四个命令:
setnx(set if not exits 维护着是乐观锁):当不存在key的时候,才为key设置值为value。setnx与set的区别:set是存在key,则去覆盖value;setnx是不存在key,则重新给key和value赋值。
getset:根据key得到旧的值,并set新的值。
expire:设置过期时间。
del:删除
实现方式:
1:获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
2:获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
3:释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放
举个例子:
SET resource_name my_random_value NX PX 30000NX表示,只有当resource_name对应的key不存在时,才能SET成功,这保证了只有第一个请求的客户端才能获得锁,而其它客户端在锁被释放之前都无法获得锁。PX 30000 是一个自动过期时间,客户端可以根据自己的业务常见,选择合适的过期时间。
数据库实现分布式锁(用的最少)
实现方式:利用的是乐观锁和悲观锁
乐观锁:在表中添加版本号的字段,每次更新前都先查询出带版本号的数据,然后再更新的时候where条件语句后带版本号条件,更新成功表示锁已占用,更新不成功表示锁没被占用。
悲观锁:利用select…for update(X锁)/select…lock in share mode(S锁),一般来说用X锁的较多,因为后续多会做写功能的实现。
注:当实现悲观锁的时候,需要关闭数据库的事务自动提交机制不然不会生效。因此java代码中应该选择主动关闭数据库的事务自动提交功能。
参考链接:https://www.jianshu.com/p/d93a4f98067e?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

三种实现方式优缺点:

使用上面Mysql实现,有如下几个问题:
1、数据库是单点的,当数据库挂掉,会造成服务不可用
2、不能设置锁的超时时间
3、这把锁是不可重入的,同一个线程在没有释放锁之前,无法再获取该锁
Zookeeper实现:
性能也比较低,但理论上也是最安全的,可以使用Curator框架实现
redis实现:
1、必须设置超时时间,假如没有设置超时时间,当一个程序获取到锁后,他崩溃了,或者因为网络问题,导致它再也无法和Redis通讯了,那么它会一直持有这个锁,而其他的客户端永远无法获取到这个锁
2、这个my_random_value是很有必要的,它保证了一个客户端释放的锁,一定是自己的锁2、加锁的过程,依然不支持可重入性,如果想实现可重入性,可以将 MAC地址 + jvm进程ID + 线程ID 作为my_random_value设置进缓存
3、依然是单点的,当redis挂掉,会导致服务不可用,假如给这个Redis挂一个Slave,但由于Redis的服务是异步的,会丧失锁的安全性
4、释放锁的过程使用lua脚本,是为了保证原子性,网上有人将加锁过程分为两步执行,先使用SETNX命令加锁,再使用PEXPIRE命令设置锁的超时时间,将这两步放在lua脚本中,也是为了保证原子性
5、超时时间应该设置成多少呢?假如方法执行时间过长,超过了设置的超时时间,当Redis已经自动删除的key,而方法依然在执行,这可能会导致程序出现发生不一致性,出现严重BUG,这看起来是个两难的问题

引申Q:如何解决redis单点故障问题?

使用Redlock算法解决单点问题:
Redlock简单直白的说,就是采用N(通常是5)个独立的redis节点,同时setnx,如果多数节点成功,就拿到了锁,这样就可以允许少数(2个或以下)的节点挂掉了。释放锁的过程则比较简单,向所有节点发起释放锁的请求,无论这个节点之前有没有成功加锁,这一点很重要,因为可能这个几点已经成功加锁,但是在返回给客户端的时候,响应包丢失了。
在Redis官网上,有Redlock算法的详细过程。在实现开发过程中,我们可以使用redisson框架中的RedissionClient类来实现Redlock算法的分布式锁。Redlock看似完美,假如我们有5个节点(A、B、C、D、E),假设发生了如下情况:
1、service1成功锁住了其中的3个节点A、B、C,而D和E没有锁住
2、节点C突然间发生了崩溃,所有的缓存全部丢失,没有持久化下来
3、将C节点进行重启
4、service2成功锁住了其中的3个节点C、D、E,获取锁成功这样,service1和service2就获取到了同一把锁。当然我们可以通过修改redis配置,将每次修改数据都进行fsync,持久化起来,但这会严重降低性能。
为了解决这一问题,Redis作者antirez又提出了延迟重启(delayed restarts)的概念。办法很简单,也就是说,当其中一个节点崩溃后,先不立即重启它,而是等待一段时间再重启,等里面的缓存全部都自动过期。这样的话,这个节点在重启前,所参与的锁全部都会过期,它在重启后就不会对以前的锁造成影响。
参考链接:https://www.jianshu.com/p/020dfba82b91

补充资料:利用jedis如何实现redis分布式锁的误区和解读:

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

2.12、 分布式session如何实现的
参考链接:https://www.cnblogs.com/mengchunchen/p/10095022.html

2.14、分布式架构与微服务的关系

2.15、分布式设计系统考虑的策略和方向

分布式系统中说白了就是由很多机器组成的集群,彼此依靠之间的网络通信,当担的角色可能不同,共同完成同一个事情的系统,如果按“实体”来划分的话,就是如下(1)节点-系统中按照协议完成计算工作的一个逻辑实体,可能是执行某些工作的进程或机器。2、网络-系统的网络传输通道,用来彼此通信。通信是具有方向性的。3、存储-系统中持久化数据的数据库或者文件存储。
基于这些,分布式系统设计策略。
(1)重试机制:一般情况下,写一段网络交互代码,发起RPC和http,都会遇到请求超时而失败的情况,此种模式可以防止网络暂时的都动,一般停顿时间很多,并重试多次后,请求成功!但不能对防止对端不能连接。
(3)心跳机制,以固定频率向其他节点汇报当前节点的状态的方式,收到心跳,一般可以认为一个节点和现在网络拓扑良好的,当然心跳汇报时,一般也会携带一些附加状态,元数据信息,以便管理。(收到心跳不是万能的,收到心跳可以确认OK,但是收到心跳却不能确认节点不存在或者挂掉,因为可能是网络原因导致链路不同但是节点依旧可以工作。)
3、副本
副本值的是针对一份数据的多份冗余拷贝,在不同节点上持久化同一份数据,当某一个节点的数据丢失时,可以从副本上获取数据,数据副本是分布式系统解决异常数据的唯一途径。当然对于多份副本你的写入会带来一致性和可用性问题,比如规定副本数为3,同步写3分,会带来3次IO的性能问题。还是同步写一份,然后异步写两份,会带来一致性问题。
4、去中心化/无中心化
系统模型的设计:中心节点,例如Mysql的单主双从,MongDB Master,HDFS NameNode,有一个或者几个节点充单整个系统的核心元数据及节点管理工作,其他节点都和中心节点进行交互。这种方式的好处显而易见,数据的管理高度统一集中在一个地方,容易聚合,相当于领导者一样,其他人服从就好,简单可行。
缺点就是高度集中,容易形成性能瓶颈,如果出现异常,就会群龙无首。
无中心化的设计,例如cassandra、zookeeper,系统中不存在一个领导者,节点之间彼此通信需要合作完成任务,好处在于如果出现异常,不影响整体系统,局部不可用,缺点就是比较协议复杂,而且需要各个节点间同步信息。

3、系统设计面试专场:

3.1、秒杀系统的设计,秒杀模块怎么设计的,如何压测,抗压手段(天猫)
引申Q:网关能够为后端服务带来哪些好处?
3.2、单机系统演变为分布式系统,会涉及到哪些技术的调整?请从前面负载到后端详细描述。(高并发的应用场景,技术需要涉及到哪些?怎样来架构设计?)

3.3、你参与的项目,画出系统架构图,集群部署图,以及服务之间的关联,设计的核心点

3.4、请画一个完整大型网站的分布式服务器集群部署图

3.5、A服务调用B服务多接口,响应时间最短方案;A系统给B系统转100块钱,如何实现?

3.6、当用户提交请求后,却立即按撤回按钮,涉及性能的数据落地问题你怎么处理
秒杀系统的优化?

3.7、画UML图
答:那么模型是什么?简单地说模型是对现实的简化。
为什么要建模?简单地说,为了更好理解正在开发的软件或者系统。

答:http://www.cnblogs.com/luyucheng/p/6340758.html

4、系统CPU和内存使用率问题

线上cpu占比过高怎么排查
线上服务 CPU 很高该怎么做?有哪些措施可以找到问题

线上服务 CPU 很高该怎么做?有哪些措施可以找到问题
top oder by with P:1040 // 首先按进程负载排序找到  axLoad(pid)
top -Hp 进程PID:1073    // 找到相关负载 线程PID
printf “0x%x\n”线程PID: 0x431  // 将线程PID转换为 16进制,为后面查找 jstack 日志做准备
jstack  进程PID | vim +/十六进制线程PID -        // 例如:jstack 1040|vim +/0x431 -

6、操作系统

Q:常用的 Linux 命令?Linux的命令(天猫)linux常用命令(问的时候都会给具体某一个场景)

看左边目录点击系统操作

Q:linux系统日志在哪里看,如何查看网络进程,Linux查看网络 内存 日志命令

mv *./html /路径
从 本地 复制到 远程
scp /home/daisy/full.tar.gz root@172.19.2.75:/home/root (然后会提示你输入另外那台172.19.2.75主机的root用户的登录密码,接着就开始copy了),复制目录加参数 -r 即可
从 远程 复制到 本地
scp root@/172.19.2.75:/home/root/full.tar.gz /home/daisy/full.tar.gz
传文件夹 用-r参数 否则有 not a regular file错误
scp -r bdump oraprod@192.168.0.188:bdump
ssh root@172.19.2.75
./xampp-linux-x64-5.6.14-0-installer.run
chmod 777 xampp-linux-x64-5.6.14-0-installer.run
启动xampp:
/opt/lampp/lampp start
停止xampp:
/opt/lampp/lampp stop
卸载xampp:
/opt/lampp/lampp stop
rm -rf /opt/lampp
cat
tail -f
日 志 文 件 说 明
/var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一
/var/log/secure 与安全相关的日志信息
/var/log/maillog 与邮件相关的日志信息
/var/log/cron 与定时任务相关的日志信息
/var/log/spooler 与UUCP和news设备相关的日志信息
/var/log/boot.log 守护进程启动和停止相关的日志消息
系统:
uname -a # 查看内核/操作系统/CPU信息
cat /etc/issue
cat /etc/redhat-release # 查看操作系统版本
cat /proc/cpuinfo # 查看CPU信息
hostname # 查看计算机名
lspci -tv # 列出所有PCI设备
lsusb -tv # 列出所有USB设备
lsmod # 列出加载的内核模块
env # 查看环境变量
资源:
free -m # 查看内存使用量和交换区使用量
df -h # 查看各分区使用情况
du -sh <目录名> # 查看指定目录的大小
grep MemTotal /proc/meminfo # 查看内存总量
grep MemFree /proc/meminfo # 查看空闲内存量
uptime # 查看系统运行时间、用户数、负载
cat /proc/loadavg # 查看系统负载
磁盘和分区:
mount | column -t # 查看挂接的分区状态
fdisk -l # 查看所有分区
swapon -s # 查看所有交换分区
hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备)
dmesg | grep IDE # 查看启动时IDE设备检测状况
网络:
ifconfig # 查看所有网络接口的属性
iptables -L # 查看防火墙设置
route -n # 查看路由表
netstat -lntp # 查看所有监听端口
netstat -antp # 查看所有已经建立的连接
netstat -s # 查看网络统计信息
进程:
ps -ef # 查看所有进程
top # 实时显示进程状态(另一篇文章里面有详细的介绍)
用户:
w # 查看活动用户
id <用户名> # 查看指定用户信息
last # 查看用户登录日志
cut -d: -f1 /etc/passwd # 查看系统所有用户
cut -d: -f1 /etc/group # 查看系统所有组
crontab -l # 查看当前用户的计划任务
服务:
chkconfig –list # 列出所有系统服务
chkconfig –list | grep on # 列出所有启动的系统服务
程序:
rpm -qa # 查看所有安装的软件包

Q:select、epool 的区别?底层的数据结构是什么?(Linux内核相关(select、poll、epoll))

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。关于这三种IO多路复用的用法,前面三篇总结写的很清楚,并用服务器回射echo程序进行了测试。连接如下所示:
select:http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html
poll:http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html
epoll:http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html
1、select实现
select的调用过程如下所示:
(1)使用copy_from_user从用户空间拷贝fd_set到内核空间
(2)注册回调函数__pollwait
(3)遍历所有fd,调用其对应的poll方法(对于socket,这个poll方法是sock_poll,sock_poll根据情况会调用到tcp_poll,udp_poll或者datagram_poll)
(4)以tcp_poll为例,其核心实现就是__pollwait,也就是上面注册的回调函数。
(5)__pollwait的主要工作就是把current(当前进程)挂到设备的等待队列中,不同的设备有不同的等待队列,对于tcp_poll来说,其等待队列是sk->sk_sleep(注意把进程挂到等待队列中并不代表进程已经睡眠了)。在设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,这时current便被唤醒了。
(6)poll方法返回时会返回一个描述读写操作是否就绪的mask掩码,根据这个mask掩码给fd_set赋值。
(7)如果遍历完所有的fd,还没有返回一个可读写的mask掩码,则会调用schedule_timeout是调用select的进程(也就是current)进入睡眠。当设备驱动发生自身资源可读写后,会唤醒其等待队列上睡眠的进程。如果超过一定的超时时间(schedule_timeout指定),还是没人唤醒,则调用select的进程会重新被唤醒获得CPU,进而重新遍历fd,判断有没有就绪的fd。
(8)把fd_set从内核空间拷贝到用户空间。
总结:
select的几大缺点:
(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3)select支持的文件描述符数量太小了,默认是1024
2 poll实现
  poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。
  https://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/index.html?ca=drs-
3 epoll实现
  epoll既然是对select和poll的改进,就应该能避免上述的三个缺点。那epoll都是怎么解决的呢?在此之前,我们先看一下epoll和select和poll的调用接口上的不同,select和poll都只提供了一个函数——select或者poll函数。而epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。
  对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
  对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。
  对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
总结:
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。
参考链接:http://www.cnblogs.com/Anker/p/3265058.html

Q:进程通信IPC(几种方式),与线程区别

https://www.cnblogs.com/CheeseZH/p/5264465.html

Q:OS的几种策略(页面置换,进程调度等,每个里面有几种算法)

https://blog.csdn.net/liushuijinger/article/details/7586653

Q:互斥与死锁相关的

https://www.1024do.com/?p=3705

7、网络安全

Q:什么是DoS、DDoS、DRDoS攻击?如何防御?
http://www.bubuko.com/infodetail-1090696.html
Q:讲下这个 XSS 攻击
https://www.freebuf.com/articles/web/40520.html
https://www.jianshu.com/p/74d6521f878f

10、常用的负载均衡,该怎么用,你能说下吗?

Nginx和其他负载均衡框架对比过吗?,简单介绍几种常用的负载均衡原理(https://www.jianshu.com/p/da6e562fa3a6)
常用的负载均衡软件详解(https://blog.csdn.net/chengxuyuanyonghu/article/details/78500297)
nginx的请求转发算法,如何配置根据权重转发
负载均衡的几种常用算法(https://www.cnblogs.com/me115/p/5000465.html)

11、MQ专题:

mq消息的实现机制
Q:MQ有可能发生重复消费,如何避免,如何做到幂等?

http://www.cnblogs.com/zhangxianming/p/8724590.html

Q:ActivityMQ的实现
答:http://heisetoufa.iteye.com/blog/1908335
项目中消息队列怎么用的?使用哪些具体业务场景?
Q: Kafka怎么保证数据可靠性?
Kafka怎么保证数据可靠性?讲了生产者端发送消息到broker持久化,分区和副本机制,消费者消费消息的at-least-once和at-most-once?怎么实现Exactly-Once?

https://www.jianshu.com/p/ebeaa7593d83

12、Lucene

Lucene底层实现原理,它的索引结构
https://www.2cto.com/kf/201701/584148.html
Lucene经多年演进优化,现在的一个索引文件结构如图所示,基本可以分为三个部分:词典、倒排表、正向文件、列式存储DocValues。

参考:http://blog.csdn.net/njpjsoftdev/article/details/54015485

13、Tomcat

Q:Tomcat reloadable实现原理
https://www.cnblogs.com/irockcode/p/6796531.html
Q:Tomcat 接收用户数据的IO原理(我回答的就是NIO,面试官说还可以,另外讲一下对Reactor模式和Proactor模式的理解)
https://segmentfault.com/a/1190000002715832
https://blog.csdn.net/qiangcai/article/details/60583330
Q:Tomcat 生命周期
https://www.jianshu.com/p/b423456804c0
Q:tomcat的各种配置,如何配置docBase
https://www.cnblogs.com/GrimMjxCl/p/9335491.html

14、工作流

你是否接触过工作流方面的技术?讲一下你对工作流的理解

答:OA系统用的比较多。工作流的作用呢,就是确保数据流程完整,保持状态一致正确,有倒计时功能的状态可以自动更新状态,发布事件。

Spring有个很神奇的功能叫做Quartz.相信很多盆友都了解,关于Quartz以后单独讲,我们知道他就是一个定时器任务,可以在我们配置的任何时间启动,实现相应的功能。我们项目中的工作流就是依托了Quartz实现了工作流的超时动作

http://blog.csdn.net/david_lou/article/details/54891354

15、dfs理解?

https://yq.aliyun.com/articles/49140

16、服务器监控(线上的服务器监控指标,你认为哪些指标是最需要关注的?为什么?)项目中的监控:那个监控指标常见的哪些?

你了解哪些服务器监控工具?答:http://server.51cto.com/sOS-565756.htm
那个监控指标常见的哪些?
名词  含义
TPS 应用每秒处理的请求数
AVG 应用对每个请求响应的平均时间
TP99    99%的请求响应时间小于等于该值
TP90    90%的请求响应时间小于等于该值
TP50    50%的请求响应时间小于等于该值
FAIL    应用对请求响应的成功、失败比率
调用链接    一次请求所经过的所有系统的集合产生的链条,反馈了系统将的依赖关系及时许
2.1服务端监控指标
性能测试通常需要监控的指标包括:服务器 Linux (包括CPU、Memory、Load、I/O)数据库:MySQL(缓存命中、索引、单条SQL性能、数据库线程数、数据池连接数)中间件:1.tomcat 2、nginx 3、memcache 4、Redis(包括线程数、连接数、日志)网络:吞吐量、吞吐率应用:Jvm内存、日志、Full GC频率
2.2客户端监控指标
LoadRunner:用户执行情况、场景状态、事物响应时间、TPS、吞吐量测试机资源:CPU、Memory、网络、磁盘空间

系统和分布式设计专题相关推荐

  1. 微课竞赛系统的设计与实现所需工作条件_全国高校教师教学竞赛备赛与设计专题研修...

    关于举办"全国高等院校教师教学竞赛备赛与设计专题培训会"的通知 教师教学竞赛是坚持"以本为本".推进"四个回归"的重要手段,是高校培养教师教 ...

  2. 让人欲罢不能的Feed流系统是如何设计的?

    作者:少强 原文:https://yq.aliyun.com/articles/706808?utm_content=g_1000064616 简介 差不多十年前,随着功能机的淘汰和智能机的普及,互联 ...

  3. 【Paper】2022_多无人机系统的分布式最优编队控制

    分享自己的一篇文章,发布在人工生命与机器人ICAROB2022,欢迎各位引用. A Distributed Optimal Formation Control for Multi-Agent Syst ...

  4. 【控制】《复杂运动体系统的分布式协同控制与优化》-方浩老师-目录

    无 回到目录 第1章 跳转链接 章节 跳转链接 第1章 绪论 <复杂运动体系统的分布式协同控制与优化>-方浩老师-目录 跳转链接 第1章 绪论 第2章 分布式跟踪控制器设计 分布式控制器 ...

  5. 大型web系统数据缓存设计-l转载

    原文地址:http://www.wmyouxi.com/a/60368.html#ixzz3tGYG9JwC 1. 前言 在高访问量的web系统中,缓存几乎是离不开的:但是一个适当.高效的缓存方案设计 ...

  6. C语言接口的封装和设计专题

    C语言接口的封装和设计专题 Win32环境下动态链接库(DLL)编程原理 导出和导入函数的匹配 与DLL模块建立链接 使用符号名链接与标识号链接 编写DllMain函数 模块句柄 应用程序怎样找到DL ...

  7. Java生鲜电商平台-促销系统的架构设计与源码解析

    Java生鲜电商平台-促销系统的架构设计与源码解析 说明:本文重点讲解现在流行的促销方案以及源码解析,让大家对促销,纳新有一个深入的了解与学习过程. 促销系统是电商系统另外一个比较大,也是比较复杂的系 ...

  8. 汽车电子专业知识篇(三十二)-整车电控系统及架构设计技术

    本文的目的是基于我们对域控制设计方法的研究,提出相关的设计过程和规则,从而设计出我们3年后的新电控系统及架构平台,也就为实现软件定义汽车和硬件通用化提供可能性.同时,也希望能为国内电控系统及架构设计标 ...

  9. OLTP 系统和 OLAP 系统的核心设计思想

    关于 OLTP 系统和 OLAP 系统的核心设计思想 数据存储系统的关于查询的典型操作: -- 第一种需求: 根据 key(1) 找 value(name,age), 单点查询 select name ...

最新文章

  1. 视频可以转换html,10 个免费的 HTML 视频转换工具
  2. 后年将有60亿部手机!
  3. 想理解Java的IO,不要从操作系统开始说起的都是耍流氓...
  4. in python_数学 in python
  5. Linux小实验——设备挂载、磁盘分区、格式化、RAID的配置、LVM配置、磁盘配额的配置方法和验证
  6. 前端学习(2887):如何短时间内实现v-for proxy代理
  7. springboot 中使用 Mybatis 注解 配置 详解
  8. mysql exists in join_子查询、left join、 exists 替代 not in
  9. MySQL无法启动服务器(1067)
  10. Java高并发编程详解系列-Balking设计模式
  11. SpaceX再获美国宇航局价值1.525亿美元合同
  12. 做游戏,学编程(C语言) 7 学习EasyX图形交互功能----flappy bird源代码
  13. Django入门-helloworld
  14. PLC数据采集解决方案,BCNet数据采集
  15. Python实现股票数据接口
  16. TBSchedule调度平台疑难解答
  17. 计算机b类核心期刊有哪些,cssci、A类、B类、C类、核心期刊都是什么等级的期刊?...
  18. 零基础学前端之SEO 基础知识学习--SEO优化学习教程【学习笔记】
  19. android 华为部分手机剪裁图片模糊问题
  20. 债务纠纷案被录入终本库了怎么办?

热门文章

  1. 好用软件推荐(1)常用软件推荐
  2. php页面设置后缩放变形,网站网页缩放后变形
  3. 华中科技大学 计算机 院士,世界著名计算机专家姚期智院士做客华中科大
  4. 横沥机械制造生产过程中,零件的加工是最基本的
  5. 国内著名大学课件大全]线点播
  6. 嵌入式C语言编程规范(个人规约)
  7. S7-200SMART案例分析——运动控制编程(二)
  8. 龙之谷冰龙linux手工服务端,【龙之谷手游服务端】3D手游冰龙商业版VM虚拟机一键安装即玩游戏客户端...
  9. Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow)
  10. QML实现异形按钮(不规则点击区域)