面试问题探讨2

445 阅读37分钟

这次主要是讨论技术的广度,对问题广度进行深入的分析和讨论。

2. 知识的广度

2.1 你们架构是怎么样的?

答: 我们的架构总体来说分为4块,分别是业务架构,应用架构,数据架构还有技术架构。 可以分开来说下我们的架构体系:

  1. 业务架构。我们是广告业务,主要是针对大流量平台的架构。 所以,我们根据不同的业务场景分为不同的架构,如广告投放/管理,数据报表等作为核心项目,基于核心项目我们拆分了,广告接口项目

  2. 应用架构。 我们对应用进行垂直化进行拆分。主要是对业务解耦和提高系统的稳定性。应用架构分层的,包括表现层,如广告投放页面,业务层,服务层,资源层。 其中业务层包括业务系统,如投放系统,图片存储系统,业务监控系统等。 服务层,主要是提供一些基础的服务功能,如用户的管理,权限的校验等。

  3. 数据架构。 数据架构我们做了数据和应用服务器分离,避免出现数据和应用的负载/资源影响应用服务器相互影响。 同时我们采用了部分读写分离。 减少主库的压力。 对于一些大表,我们进行表拆分。如小时数据统计表。对于一些经常需要查询或者需要计算的数据,我们采用redis缓存来处理。

  4. 技术架构。我们的前期是自己在AWS ec2搭建相关的服务,如redis, mysql等。 后期我们测试aws服务,同时也调研了其他的团队的aws使用情况,从服务的稳定和我们需要的服务都有相应的解决方案。 使用的服务包括,ELB解决负载均衡的问题,使用了RDS处理数据库问题, 使用了Redis 做缓存和消息队列的工作。 同时还使用s3做对象处理的服务。 解决素材本地化的问题。 在技术架构的时候我们考虑到aws的可监控,可回滚,可在线扩容等都提供解决方案。 我们就技术总体架构是构建在aws服务上。

2.2 对CodeIgniter框架做了什么深度优化?

答:CodeIgniter 是一个非常老的框架了。 采用了还比较老的5.3以前的下划线的命名方式。 我们使用了版本是2.2,我们在此做的优化包括:

  1. 增加了composer 加载类的机制。 这个跟CI的类加载机制还是不一样的。
  2. 为了更好开发项目,我们扩展了Service层。Service层主要应用/控制器更好的提供服务。
  3. 对于CI里面一些特性或者遇到的问题做了扩展。 写死的超时机制,xss机制等做了一些扩展
  4. 其他的增加了一些扩展的组件和工具等。
2.3 JS的原理是是什么? 查看
2.3.1 javascript 是怎么个东西? @todo

答: javascript 是前端的执行脚本语言。译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。
这两者的区别用一句话来概括就是:编译器是将源代码编译为另外一种代码(比如机器码,或者字节码),而解释器是直接解析并将代码运行结果输出。javascript 采用的是单线程的方式进行处理

2.3.2 javascript 为什么是单线程的?

答:javascript 的单线程,主要是考虑js执行过程中多线程保持同步带来的复杂度, 如在执行事件的时候,一个事件对创建一个element,而另外一个删除了element,主要避免多线程的同步问题的复杂度。

2.3.3 javascript 事件回调函数和机制是什么?

答:js把function 作为一个对象的类型,这样通过参数类型的转换从而实现方法的回调操作。 而这种机制可以异步处理的方式,避免同步等待的过程。 尤其在xhttpRequest使用的场景很多。

2.3.4 javascript prototype是怎么样的?

答:我们都知道js基本上都是函数的表达式,就好比面向过程编程一样,通过函数的调用。但是这样随着项目的负载,使用的js代码越来越复杂在一定的程度上就不好处理了。这样js其实也有面向对象的一些特性,而原型就是可以设置自己的对象,并且可以包含其方法和属性信息。这样在一定的程度上解决了js对象的扩展问题。

2.4 ajax的机制和原理是什么? @todo

答:Ajax 是javascript 的异步回调的机制,主要是使用xmlHttpRequest 请求的方式。 Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。 ajax核心就在于对客户端和服务之间的数据通信进行了一层封装,支持的服务有:实时验证,实时刷新,实时更新用户,作者和标题,从而可以快速的获取服务端的数据,并动态的使用javascript填充区域的数据。

2.5 Redis
2.5.1 Redis的机制和原理是什么?

答:Redis 是一个高效的分布式缓存存储和管理机制。 它的实现原理,首先采用客户端和服务端c/s模式。 客户端请求redis服务端,服务端采用多路事件模型libevent 其次, 线程对事件的处理包括创建,更新,删除等操作,也内存分配和管理策略。 使用的分配算法包括slab ,申请块内存的方法,管理内存算法主要使用LRU算法机制。 保证Redis的高速缓存特性。 最好,处理的结果返回。

2.5.2 Redis 订阅和发布机制

答: Redis 订阅和发布机制,主要是消息的生产者把消息放入channel中,其中channel可以多个。 而消费者如果关注/订阅了这个Channel消息类型,就会广播给相应的消费者。 从而达到订阅和发布的效果。

2.5.3 Redis 你们的吞吐量是多少?

答: 我们现有使用Redis不是很充分,主要是使用场景还是广告数据的计算和日常的缓存处理。 我们测试的吞吐量大概5k。 我们Redis配置,采用两台16GRedis作为集群处理。

2.5.4 Redis 的事务机制是怎么处理的?

答: Redis 为了支持事务的操作也增加了事务的回滚机制。 在redis操作的时候,可以redis 会把开启事务的操作加入到队列中,然后一起提交。 如果中间有事务的异常所有提交的都将失败。 具体的命令:Redis事务的实现需要用到 MULTI 和 EXEC 两个命令。如果客户端在发送EXEC命令之前断线了,则服务器会清空事务队列,事务中的所有命令都不会被执行。

2.5.5 如果达到每秒1w/s或者10w/s你打算怎么来处理?

答:redis单机的话处理2w其实就很容易产生数据包问题。我们算下,如果平均一条记录是0.1k,那么2w 就是 2M/s 如果1G内存可以处理500s,大概预估10分钟。 16G可以存储的内存是3个小时热数据。而对于一些需要技术28天归因的redis数据失效时间比较长,所以redis还是比较难满足10w这样大的体量的缓存机制。 可以采用业界比较成熟的的kafka,但是具体这项技术的引进需要各种指标的测试还要调用具体的坑有哪些。

2.5.6 Redis 使用遇到的坑有哪些?

答:现在体量还不是很大,暂时没有遇到大的坑。 有些坑是开发同学在设置redis失效时间比较长产生的,影响redis挤压的内存比较多

2.5.7 Redis 的集群和分布式原理 @todo

答: Redis集群主备,主要是Redis aof文件的同步处理。 AOF 类似mysql 的binlog, 同步的机制主要是主开一个线程写aof文件,具体根据aof配置策略,然后从开启两个线程,一个读取aof文件,并且把aof写入中继器文件。 从而实现主从可以同步。 而Redis 分布式主要解决的时候数据的一致性,事务和数据的分片。 Redis 跟memcache 一致性hash算法不太一样,使用了键和槽的hash桶算法。 常用了hash算法如crc32, 把不同的键放到不同的hash桶中。 而保证不同节点都可以真正的数据同步使用。

redis hash槽一般有16384个槽点,而对节点的存储采用地址拉链法,不断的把在节点的数据节点延伸。这样可以满足redis的节点的分布。redis解决分布式一方面支持了分布式事务,另一份方面对服务器槽点服务器进行逻辑映射。所以节点还是存在一些问题的。

2.6 Elasticsearch机制和原理是什么? @todo

答: 在我们项目中使用es的技术主要还是探索阶段。我们是想用来解决报表数据查询比较慢的问题,现在对es了解主要是方案的探讨。我可以简单聊下我们对es调研的方案和一些简单的理解。从对es的了解,es的主要是解决搜索和分布式问题。 而搜索这一块还是使用lucence 框架,对lucence框架基础上增加索引分片,分布式等解决方案。 提高了搜索的效率。 为了更加方便和使用es,es挺比较restful的简单清晰的请求方式。 elasticsearch 具体的原理,可以分两块来探讨。 一块是lucence 搜索的机制,另外一个是lucence 分布氏技术。 lucence是使用java开发的全文搜索引擎的框架。为什么它能够这样有效的作为关键词进行搜索呢?这个搜索引擎的设计思路是模拟我们搜索的过程来构建的。 我们输入关键词然后希望能够显示关键词在不同的文档匹配的情况。

  1. 对文档的所有内容进行关键词切词。切词的算法总体归位三类,基于字符串的匹配,基于单词的语法的,还有基于统计的。具体可以查找相关算法。
  2. 采用到排序的方式记录关键词的在文档的位置。并对关键词进行构建索引。
  3. 怎么样来构建非常好的索引是搜索引擎的关键。我们的期望,查询要快,内存要占用的少,磁盘浪费少等我们常见的方式可以使用hashmap作为索引但是这种方式太占用内存了。我们也会想到关系数据库的b树索引。b树可以作为索引,但是b树的索引更新的时候效率很低,不适合频繁的采集和更新操作。后面有人提出对hashmap基础上增加了字典和前缀的方式来提高索引的效率。这就是比较著名的fst算法。它的本质就是对索引的关键词前缀下不断建立关联节点。对于重复的词来说可以省去重复词占用的空间,大大的提高使用的效率。
  4. 最后是文档内容的输出,可以对查询命中的关键词进行压缩输出,提高使用的效率。

另一个就是es支持分布式理念把其整合系统中去。要满足分布式的处理一般需要解决这样一些场景的问题:

  1. 进行数据的分片,这样才可以把一个大的问题拆分成更小块,保证处理起来更加高效。同时还需要对分片的数据进行replication,建立副本集。
  2. 要均衡的分配到不同的节点中,这样避免节点分配不均产生的问题。常见的算法有一致性hash分配算法,还有redishash槽的算法。
  3. 对于节点的管理,包括增加和删除节点都可以保证其有效性,并且能够重新均衡分配。
  4. 支持分布式事务的原则。一般参考cap原则,一般高可用和分区都可以满足,强一致性比较难满足。主要还是异步的事件同步机制会出现同步失败重试和延迟的情况,所以,我们支持最终一致性的方式。 对于es基本满足前面说的几点,除了满足这几点和增加了,节点发现的方式。对于实效的节点能够检测替换和恢复等操作。 还有更多细节的其特性需要根据实际的场景再进行其利用。
2.7. Supervisor 主要用来做什么? 它的机制和原理是什么?

答:Supervisor 技术选择主要是考虑到一些定时任务会出现中断的情况。 supervisor就是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。所以我们选择了Supervisor. 使用Supervisor,把所有的守护进程都配置到它的配置里面。然后启动的Supervisor 就会对所有的进程去检测,如果存在中断的情况,会自动重启一个新的进程进行处理。

2.8 你所了解的TCP/IP协议 @todo
2.8.1 tcp的理解

答: TCP是传输层的协议,并且是可靠的数据传输协议。 我们都知道OSI 有7层协议, 在tcp IP协议中,其中会话层,展示层, 应用层合并为应用层。 所以我们经常讨论TCP/IP 4层模型。 现在就成了,应用发送数据包->TCP->IP->数据链路层,最后物理层。 TCP从这个分层结构来看,TCP首先要解决跟应用层的交互,也就是经常的3次握手协议和4次关闭连接协议,这里会涉及三个概念,一个是syn同步序列号,ack确认码,fin完成标识。来保证数据可靠性。 TCP层主要是解决传输层的问题,那解决了什么问题?

  1. 数据包标准化的问题。 如果数据包的大小没有规范,这样不同的路由器,不同的网络对数据包的解析都没有规范。 基于此,有挺多概念的如ack,window,syn 等都是TCP数据包大小。 tcp规划了20个字节对于数据包头进行规定2个字节源端口,2字节目标端口,4个字节放syn,4个字节放ack,2个字节放window,最后2个字节放偏移量,flag等内容。校验码2个,还有紧急指针2个。总共20个字节
  2. 数据包丢包重传的优化。 TCP是可靠的协议这样就需要解决数据包的重传问题,常见了算法有RTT算法。主要是跟进丢包时间差来决定是否需要重传。

  1. 数据包的重复包的问题。 如d-slab 算法,主要对确认的块进行验证。
  2. 数据包传输的调度问题,如网络阻塞,网络。 这里主要是根据window来调度。window 对数据包分为4类,1类,数据包已发送已接受,2类,数据包已发送还没有接受,3 数据包已经发送,等待确认 , 4. 数据未发送,也未确认。 解决的方式有,1)慢启动,2)拥塞避免,3)拥塞发现,4)快速恢复。
2.8.2 IP协议的理解

答:IP表示网络协议层,主要是根据传输层和数据链层制定报文结构,IP头也是20个字节。主要内容包括,IP地址,目标地址,协议版本,协议的ttl,协议的校验,和协议的的标识。主要是支持arp地址的解析。

2.9 你所了解的HTTP协议
2.9.1 HTTP 的版本情况是怎么样? @todo

答:HTTP 有3个版本, 0.9版本这个版本只支持get请求,已经停止了使用了。1.0版本支持get,post,put,delete等常见的http的方法。 1.1 版本在1.0版本增加了一些特性,如重复请求的缓存机制

2.9.2 HTTP的原理和机制

答:HTTP是无状态的超文本的协议,主要解决的是客户端和服务端的通信。 我们试想下如果没有HTTP协议,我们会怎么来进行客户端和服务端的通讯。 我们的通讯的基本需求,建立连接,然后进行增删改查的操作。 而如果没有协议的话,就好比一条马路大量的来往车辆没有自己的规则和标准。我们就需要,不同的区域有不同的协议来协商数据的传输。而HTTP协议就是这规则和标准,统一所有的传输方式,虽然不能够说是最好的,但一定是最广泛的传输协议。其实自己也可以在开发制定自己的传输协议。 HTTP 是在应用层跟传输层建立的协议标准。首先建立连接采用TCP/IP 三层握手协议建立连接。 采用请求和相应的机制进行通信。 在通信过程中采用了GET, POST, PUT,DELTE 方法,来满足交互。 除了解决基本的客户端和服务端的通信也解决其他的问题。 包括HTTP无状态怎么来做区分和标识,采用了cookie或者session的技术。 而对于经常的重复请求和重复的相应,引进了Cache机制。 如果Cache-Control

  1. HTTP 的通信规则是基于URI,统一资源标识符,来定位资源。 而所有的服务端提供的服务都可以通过统一标识符来处理。解决连接的问题。
  2. HTTP在解决通信连接的问题,然后解决数据的传递问题。 对于数据的请求采用了各种请求数据的传递参数,如json参数,字符串传输等。 而相应也有同样的指定。解决数据格式的问题
  3. 解决权限控制的问题,cors跨域的控制
  4. 在1.1版本更是对连接的效率和重复连接做了大的优化。包括采用了长连接机制,减少建立和启动的成本,还有优化了缓存控制机制,有缓存的年龄,过期的时间,还有采用etag的缓存检测机制等。
2.9.3 HTTPS 是怎么样的?

答: HTTPS 是在HTTP加上了一个s,这个主要是让http更加的安全可靠的传输数据。 那HTTPS是怎么来解决安全这件事情的呢? 一般来说计算机解决安全主要从两方面着手,一方面是权限控制,如只有满足某些条件你才能够访问这个资源或者服务,另一方面就是通过加密的手段。 我们试想一下,使用HTTP在使用过程中的不安全的地方。 首先HTTP是无状态的,这样任何的代理都可以”假传圣旨“,这样就容易出现不能够识别真实的情况。 而这种情况呀在http其实已经可以通过session验证和客户端加密和服务端解密来解决。 但是在客户端加密和服务端解密的过程中有一个重要的隐患:客户端和服务端一般信息不怎么加密,针对重要的信息才进行加密,而客户端的代码一般是暴露的,如果对客户端的加密代码进行研究是了解服务端发送的信息怎么解密的。

针对这个情况,可以对于客户端每次请求的所有数据都进行加密传输,然后服务端进行解密处理。但是涉及到客户端和服务端的秘钥怎么传输的情况。如果是写死在客户端,那么就很容易被客户端反编译查看到,如果是通过http建立连接来传递秘钥的话,自然会被中间的代理劫持。 针对http带来的不安全,就出现了HTTPS的设计。

HTTPS 设计首先需要解决的是客端户和服务端数据都需要加密,并且秘钥最好是可逆和不可逆混合加密的方式来处理。 最后通过第三方的CA证书认证,过滤掉代理的劫持,保证数据的正常安全的通信。

具体的设计流程如下:

  1. 客户端请求服务器,首先会验证服务器CA认证的证书是否合法。具体主要是浏览器根认证里面会根据关联的CA认证机构进行查看是否合法/存在。
  2. 客户端浏览器验证CA正常后,会把自己的私钥以非对称算法进行加密,如RSA算法(基于公因数分解)加密传输后,服务端就知道客户端的秘钥了。
  3. 服务端采用对称加密服务端秘钥,如dea,aes并且以md5(基于hash分布),sha散列算法加密。这样客户端也知道解除服务端数据。然后客户端和服务端都可以正常的数据加密操作。而中间人会被过滤了。
2.10 你说下负载均衡(ELB)的原理? ->done

答:负载均衡要满足的做到流量的分发,均衡的分发到不同的节点。而我们http请求一般通过域名来请求,这样我们需要做好基于域名流量的策略。常见的策略有,dns轮询,负载均衡器里面内置dsn管理和对dns的反向服务器的代理或者服务器流量的分发。除了dns轮询,还有流量的比例和比重,把流量均衡到不同的服务器节点上。而不同的策略可以根据业务的场景来满足需求。处理流量的分发,还有流量的检测和负载均衡的主从来保证负载均衡的稳定,并对存在问题的节点检测问题,均衡处理。除了分发流量,还可以基于流量的内容过滤,如过滤色情,暴力等内容的信息。

2.10.1 怎么来搭建现有的架构体系,而不是使用aws的服务?

答:在使用aws服务前,所有的服务都是我们可以搭建的,后面是从服务器的成本和其他团队的使用稳定性和高可用等多因素考虑。从新搭建架构体系,可以把一步步的替换。如elb,我们可以自己通过搭建lvs,规划好服务器的地址和管理的dns,进行节点的配置,最后通过数据库的配置进行处理。满足elb中使用到的特性,并且对其进行基准测试,评估成本看是否方案是否可行。同理其他的服务和组件也是同样的思路和解决方法。

2.11 怎么来做到自动伸缩的?->done

答:自动伸缩主要是要解决不同的服务器的各项指标的检测,更重要的是满足服务器要大流量的增长的同时也需要考虑服务器闲置产生的浪费的情况。从这个角度来看,要做一些必要的事情:

  1. 服务器的监控,
  2. 对服务器监控设置规则,可以按照机会或者规则进行触发,如CPU使用超过70%自动添加机器。
  3. 对于历史的流量时段或者特别的节假日,我们要考虑提前启动服务器来满足其流量的情况。
  4. 容错的处理,自动检查存在异常的实例,把这些实例进行替换保证系统正常完成执行操作。
2.12 S3对象存储的原理是什么?->done

答:S3的对象存储。主要是用于管理一些文件还有一些日志信息。在没有使用s3的时候,我们采用了更多的是写入本地磁盘或者自己搭建简单的文件系统。s3不但满足了日常的文件系统的需求,更重要的提供了高可用的服务,同时也可以专注于场景开发。 简单说下:

  1. 支持了各种文件对象的存储,存储性能比较快
  2. 有安全的验证,并且对象进行主备消除了单点等。
2.13 说下自动伸缩的机制是什么?->done

详见:2.11

2.14 你所了解的Mysql集群 ->done
2.14.1 Mysql 查询过程是怎么样?

答:mysql是关系数据库,它是c/s架构模式。客户端和服务端采用半双公的方式,客户端请求后,需要等服务端的返回,同样,服务端的返回,客户端需要接收完成。 总体的查询过程有这样几步:

  1. mysql客户端发送请求,而请求协议一般还是基于http的协议方式
  2. 服务端接收到请求后会查看缓存中是否存在结果命中,有就直接返回
  3. 对于未命中,把sql构建成查询树,并对语法进行验证,并且进行预处理权限的验证,验证OK后。根据查询树进行查询任务的优化器中,然后检查是否存在查询的缓存的task,存在直接使用查询的数据。然后把没有缓存的sql。优化器根据查询优化的最小成本去优化。
  4. 放到优化器引擎去调用选择的存储引擎,然后根据存储引擎返回的结果进行数据的返回。然后优化器统一计算计算结果,然后进行输出。 这样就是mysql的简单的查询过程了。
2.14.2 Mysql集群的机制

答:mysql的集群,主要是避免数据库的执行单点情况。mysql集群是对mysql的水平扩展,常见的方式有,主从的同步的实现,也可以一主多从的操作。 集群构建后,需要对主从库进行检测,如果主库挂掉了,可以根据最新的sql时间从库作为主库,然后起来写bin log文件。主库负责写,从库负责读的操作。

2.14.3 Mysql 主从同步的机制

答:作为主服务器需要开启一个线程主要dump sql任务, 而从库需要把线程主库的dump sql写入到从库的中继器文件中,然后开启一个sql 线程,把中继器文件写入从库中。从而实现主从的同步。

2.15.4 说下你了解的Mysql的索引机制是什么样的?
2.15 Mysql 事务
2.15.1 Mysql的事务情况是怎么样?
2.16 说下用户从打开你网站的技术过程? ->done
2.17 代码工具的路径是什么? ->done
2.18 文档化工具实现逻辑是什么? ->done
2.19 PHP
2.19.1 解析机制是什么样的? ->done

解析机制主要是分为4层,zend引擎,PHP层级,SAPI服务应用调用,最后是应用调用

zend引擎:是php的核心,这个是纯C语言编写包括,词法,opcode,也支持对底层的数据结构的处理,如hashtable, 并进行内存的管理,使其更加方便使用。 Extension: 这个是PHP的扩展,包括增加一些PHP的驱动,里面常用的mysql,redis的扩展;对于常用的函数,可扩展的性能的工具的处理

SAPI : 服务的外围的编程接口, 通过sapi,应用可以直接调用服务公共的接口,也可以对Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的一个设计,通过sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。SAPI也负责对cgi进行解析和命令行的调用,

Application : 应用层,这就是我们的应用程序,可以通过webserver 来实现web的服务操作和开发工作

2.19.2 PHP 解析器的opcache的是什么时候引进php版本,具体的实现机制是什么? ->done
2.19.3 PHP Hash table的数据结构逻辑

Hash table 实现了简单的hash结构, 并且支持了增加附加的双向列表, 提供正向和反向的遍历数组的信息。

这里涉及到的数据结构包括, Hash的数据结构, 双向链表,PHP关联数组,PHP索引数组信息。 这里的双向链表主要是为了快速的遍历和快速的删除操作。 PHP索引数组对于数组的Key进行归一化的处理。

2.20 你们系统的加密算法是什么? 为什么要使用这个? ->done

常见的加密算法分成3类 对称加密算法: DES, AES,3DES DES 分组式加密算法,以64位为分组对数据加密,加解密使用同一个算法。 而3DES对DES进行加密进行3次,使其更加安全和高效。

非对称加密: RSA,DSA(数字签名) hash加密算法:Hash算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。(hash加密算法)高级加密标准算法,是美国联邦政府采用的一种区块加密标准,用于替代原先的 常见的包括MD5,SHA, SHA-1, HMAC

DES:对称加密, 指加密和解密使用相同密钥的加密算法。

2.21 有了解过分布式吗? 简单说下你的理解
2.21.1 分布式的机制是什么?

答:分布式的方式主要是考虑任务的拆分,把一个大的事情不断的拆分成不同的小的块。 从使得各个拆分的点可以组织在一起进行处理。 分布式需要解决了的问题包括任务的拆分,还有任务的聚合处理,保证任务处理结果的一致性。 那具体怎么来达到分布式的效果呢?

  1. 需要解决分布式拆分的问题。 把一个大的服务拆分成小的服务,进行服务的注册和管理。(拆分的服务直接是可以保持通信和资源的共享)
  2. 需要解决分布式的事务的情况,保证事务处理的一致性,一般是数据的最终一致性的要求。 而需要保证事务的一致性一般采用的是主服务收到从服务的一致性的确认之后进行判断是否的执行还是中止/回滚。
  3. 分布式还有解决的是高可用性的问题。 怎么保证分布在不同的节点的服务是高可用的? 这个需要对不同节点进行单点容错,并且检测,保证数据的高可用性。 这就是我们常见的副本集。

现有的一些框架如dubbo,spring clond在一定的程度上提供了对分布式服务解决方案。

2.21.1 分布式和集群的区别

答:分布式主要是解决垂直的任务的拆解问题,而集群是解决水平的扩展问题。 分布式更多的是需要解决业务和服务的拆解,保证每个服务是高可用的。 并且各个服务是独立可用相互使用的。 并且需要保证各个节点是正常运转的。 而集群更多的是水平的扩展,消除单点的情况,并且增加整体的处理能力。

2.21.2 CAP原则

答:CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

三种原则: CA without P : 如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。

CP : 牺牲可用性 AP : 保持高可用性

但如果以算法划分,到能分出几类: 1.以Leader选举为主的一类算法,比如paxos、viewstamp,就是现在zookeeper、Chuby等工具的主体 2.以分布式事务为主的一类主要是二段提交,这些分布式数据库管理器及数据库都支持 3.以若一致性为主的,主要代表是Cassandra的W、R、N可调节的一致性 4.以租赁机制为主的,主要是一些分布式锁的概念,目前还没有看到纯粹“分布式”锁的实现 5.以失败探测为主的,主要是Gossip和phi失败探测算法,当然也包括简单的心跳 6.以弱一致性、因果一致性、顺序一致性为主的,开源尚不多,但大都应用在Linkedin、Twitter、Facebook等公司内部 7当然以异步解耦为主的,还有各类Queue

2.22 可以说下你理解的protobuf协议吗?

答:protobuf 是google 开发出来的二进制协议,主要是解决数据的传输带来的问题。 我们常见的传输协议主要使用json的方式,而json优点当然很清晰明了,结构也比较简单。 也使用使用xml,解析和可读性比较差,但是对于返回的数据比较好定义,包括数据的格式等都非常明显。 它们有个非常大的问题就是返回的结果数据比较大,消耗网络的传输和处理。 而protobuf就非常聪明的方式来解决协议上的问题了。 protobuf主要采用的协议方式是二进制对象的方式,所有的key多使用序号来生成,这个样4个字节基本上可以满足所有的key的填充,而内容也对字符,对象进行压缩生成二进制码,在一定的程度是减少了数据的传输成本,提高的数据的交互效率。

protobuf非常优秀的点:

  1. 代码生成机制,数据解析类自动生成。这样值需要配置proto文件就可以生成必要的信息
  2. 支持向后兼容和向前兼容
  3. 支持多种语言的方式
2.23 简单说下你在项目中使用到的CI和TP框架

答:CI是框架比较简单。主要是采用MVC模式,可以非常方便的代码进行封装处理。 而路由也是非常简单的方式,采用类和方法的路由方式。 而这些方式在一定的程度上开发只需要重点关注于项目的具体处理而不需要考虑具体的逻辑场景。 TP框架是国内的一款框架,第一次接触的是TP框架,也对MVC进行封装,特别是提供了简单的M方法,可以非常方便的进行SQL的查询和处理,但是如果都把sql放到M方法体里面,很容易产生代码和模板的混乱,特别而是现在很多进行业务场景的拆分,这套机制是很难满足业务的需求。 随着TP的改进,由之前的基于数据挖掘的内容改变成

2.24 技术功底
2.24.1 简单说下网络I/O模型是怎么样?

答:网络的I/O主要分为两种,一种是同步等待的I/O,另外一种是异步等待的I/O模型。 同步机制就是我们常见的socket io, server不断的监听client是否对数据进行发送数据的请求,然后把数据请求进行处理。 而另外一种是基于异步的I/O模型,这种模型主要解决的问题是异步的处理机制。 这样增加了一个I/O缓存去和I/O的事件注册机制,采用的模型可以是epoll异步机制。 多路复用的I/O事件模型,更多的是解决等待的处理情况,客户端的情况会优先放到注册事件列表/队列中,然后服务端会有事件回调,处理好的服务端会优先查看下是否还有时间服务没有处理,如果存在,则进行接口的调用。 从而实现数据的接口调用操作。 总体来说有5中I/O模型:

  1. 阻塞IO :读必须要在写之后才能够读
  2. 非阻塞IO:每次轮询检测用户有没有执行好(主要是看文件描述符的缓冲区是否就绪),当书记报准备好的时候,就进行拷贝的工作。当数据包没有准备好的时候也不阻塞程序,直接返回未准备好,等待下一吃用户的轮询。
  3. 信号驱动IO:这个就是告诉系统内核,你准备就绪了就发送一个信号告诉我来调用事件的处理机制。
  4. IO复用:对了一个select 对文件描述符号进行轮询,当发现某个文件描述符就询后就进行处理。这个是对阻塞I/O的支持多个文件的操作
  5. 异步IO: 就是信号驱动IO和IO复用结合在一起,一方面是告诉内核我有事件信号就直接通知我调用进程,另一方面可以注册多个文件,对多个文件描述符进行监听处理。
2.24.2 进程调度的机制是怎么样?

答:对于操作系统而言,进程就是一个Task,而不同的进程调度就是任务的调度。你任务的调度可以分为抢占式的还是非抢占是的进程调度的方式。
而常见的任务调度都是基于时间片切换的方式,如每个10ms进程进行切换调用。 同样的也可以进程采用优先级的方式进行进程的调度。 都有一些刚启动的进程的优先级 linux可以通过nice值来调整优先级,从而使得优先级更好的进行出来。

而抢占式的方式常见的方式是FIFO,当前得到的进程要全部使用完之后才会退出,这样对资源的消耗是非常的巨大的。

2.24.3 说下内存的模型是怎么样?

答:内存是存储器中非常快速的方式。存储器分为主存和辅助存储,辅助存储主要是硬盘,磁盘等,而主存包括内存和高速缓存,一般而言高速缓存的空间非常的小,可操作的空间非常小,一般是操作系统内核进行调度。 所以我们更多的是关注于内存的处理。 内存的主要数据和地址主要是从辅助存储加载进来处理的。 那我们具体说下java语言的内存模型: java的代码主要是通过类加载器,加载到JVM虚拟机里面。

  1. java的内存数据区域对于java 代码进行分类。 类里面的方法放到方法区,变量和引用对象的变量放到栈区,而新建的对象和数组放到堆区,java里面的线程放到线程池区,而对于程序的加载都有程序计数器记录,记录当前线程执行的内存地址。方便线程之前的切换,还能够还原到初始状态。
  2. Jvm 虚拟机编译java的代码,然后通过java的代码执行生成class文件 。
  3. Jvm 执行器(JIT)把class 文件加载到内存中,对于需要释放的空间有java GC进行内存的回收处理。
  4. JVM 编译后链接c语言的本地接口的调用和数据的返回处理。
2.25 CSS
2.25.1 css的机制是什么

答:css 是层叠样式文件。 css主要是对Dom进行加载后的查找和渲染。 css会定制它的框架的基本样式,而在框架的样式风格下可以自己定义样式的风格。 css 需要解决两件事情:

  1. 怎么进行DOM 的查找,这个常见的是使用class名称或ID进行查找。除了这些查找有大量的方式是使用过滤的方式,通过节点通配符来获取查找的节点。 如根据p段落来查找
  2. 怎么对查找的节点进行渲染,渲染需要考虑的是客户端的大小和兼容性问题。 对于选择的区域可以采用相对大小也可以采用觉得的大小的方式来保证节点渲染精确性。
2.25.2 CSS盒模型

答:CSS的盒模型盒子里面有盒子内的坐标和外部的坐标。 我们常说的内间距和外间距。 而间距包括上下左右的间距大小。 通过间距大小可以控制盒子的位置

2.26 对hashMap的深度理解,是怎么实现get和put

答:HashMap 是对Map接口的实现,里面有两个必要的方法,一个是hashcode,来定位hash存放的位置,两个是equals方法来判断对象是否匹配。 这个是使用层面的,而真正的hashMap可以使用方式是hash桶,而hash桶的的算法可以是多种如crc32效验法。你hash的桶可以使用拉链法,不断的地址需要延伸。 这样就可以真正的实现hash的在桶的基础上不断的扩展。

2.27 分区分服,查看

答:游戏有个特点,非常的依赖于网速。如果网速的性能差,经常出现掉线,那么一般游戏基本上是没法玩的。 一般的分区的考虑是跟进不同的网络服务商和不同的大平台来划分,如电信网络一区,网通一区。或者QQGame和QQ空间 不同的区支持的网络信号是存在差异的。 在分区之后,会发现一些大的区在游戏体量非常集中的时候会出现非常多人的情况。 这时候需要在区的基础上进一步花费,采用逻辑分服。

而分区分服务的实现:

  1. 根据用户量进行预估来判断大概需要开启多少个区和多少的个服满足前期的用户的进入,加上有100w用户。 我们可能会分为2个电信区,2个网通区。
  2. 在具体的架构上来看,不同服务的DB是不同的。一般不互通。 从运营的架构机制来,用户群会集群进行分发到不同的服务,而不同的服务下面有不同的服务器节点进行处理。 然后进行游戏的服务请求。
2.28 加密技术
2.28.1 RSA加密
2.28.2 DES加密
2.28.3 AES加密
2.28.4 md5加密
2.28.5 sha加密
2.29 Kafka技术

3. 弹力设计

3.1 幂等性作用和应用场景是什么?
3.2 隔离设计作用和应用场景?
3.3 异步通信设计作用和应用场景?