16.知识面、Linux、网络

知识面、Linux、网络


1.解释什么是 MESI 协议(缓存一致性)
2.谈谈 reactor 模型
3.Java 9 带来了怎样的新功能
4.Java 与 C++ 对比,C++ 或 Java 中的异常处理机制的简单原理和应用
5.简单讲讲 Tomcat 结构,以及其类加载器流程
6.虚拟内存是什么
7.阐述下 SOLID 原则
8.请简要讲一下你对测试驱动开发(TDD)的认识
9.CDN实现原理
10.Maven 和 ANT 有什么区别
11.UML中有哪些常用的图
12.Linux 下 IO 模型有几种,各自的含义是什么。
13.Linux 系统下你关注过哪些内核参数,说说你知道的
14.Linux 下用一行命令查看文件的最后五行
15.平时用到哪些 Linux 命令
16.用一行命令输出正在运行的 Java 进程
17.使用什么命令来确定是否有 Tomcat 实例运行在机器上
18.什么是 N+1 难题
19.什么是 paxos 算法
20.什么是 restful,讲讲你理解的 restful
21.什么是 zab 协议
22.什么是领域模型(domain model)?贫血模型(anaemic domain model) 和充血模型(rich domain model)有什么区别
23.什么是领域驱动开发(Domain Driven Development)
24.介绍一下了解的 Java 领域的 Web Service 框架
25.Web Server、Web Container 与 Application Server 的区别是什么
26.微服务(MicroServices)与巨石型应用(Monolithic Applications)之间的区别在哪里
27.描述 Cookie 和 Session 的作用,区别和各自的应用范围,Session工作原理
28.你常用的持续集成(Continuous Integration)、静态代码分析(Static Code Analysis)工具有哪些
29.简述下数据库正则化(Normalizations)
30.KISS,DRY,YAGNI 等原则是什么含义
31.分布式事务的原理,优缺点,如何使用分布式事务?
32.布式集群下如何做到唯一序列号
33.Http请求头都有哪些,分别是什么意思
34.http请求结构,分别是什么
35.HTTPS 的加密方式是什么,讲讲整个加密解密流程
36.HTTPS和HTTP的区别
37.HTTP连接池实现原理
38.HTTP集群方案
39.Nginx、lighttpd、Apache三大主流 Web服务器的区别
40.是否看过框架的一些代码
41.持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些
42.数值提升是什么
43.你能解释一下里氏替换原则吗
44.你是如何测试一个应用的?知道哪些测试框架
45.传输层常见编程协议有哪些?并说出各自的特点


1.解释什么是 MESI 协议(缓存一致性)    参考链接        参考链接

当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。
MESI协议中的状态
CPU中每个缓存行(caceh line)使用4种状态进行标记(使用额外的两位(bit)表示):
M: 被修改(Modified)
该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该缓存行中的内存需要在未来的某个时间点(允许其它CPU读取请主存中相应内存之前)写回(write back)主存。当被写回主存之后,该缓存行的状态会变成独享(exclusive)状态。
E: 独享的(Exclusive)
该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态(shared)。同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。
S: 共享的(Shared)
该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。
I: 无效的(Invalid)
该缓存是无效的(可能有其它CPU修改了该缓存行)。

2.谈谈 reactor 模型        参考链接        参考链接

  反应器设计模式(Reactor pattern)是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理。 Reactor模式主要包含下面几部分内容。
          初始事件分发器(Initialization Dispatcher):用于管理Event Handler,定义注册、移除EventHandler等。它还作为Reactor模式的入口调用Synchronous Event Demultiplexer的select方法以阻塞等待事件返回,当阻塞等待返回时,根据事件发生的Handle将其分发给对应的Event Handler处理,即回调EventHandler中的handle_event()方法
          同步(多路)事件分离器(Synchronous Event Demultiplexer):无限循环等待新事件的到来,一旦发现有新的事件到来,就会通知初始事件分发器去调取特定的事件处理器。
          系统处理程序(Handles):操作系统中的句柄,是对资源在操作系统层面上的一种抽象,它可以是打开的文件、一个连接(Socket)、Timer等。由于Reactor模式一般使用在网络编程中,因而这里一般指Socket Handle,即一个网络连接(Connection,在Java NIO中的Channel)。这个Channel注册到Synchronous Event Demultiplexer中,以监听Handle中发生的事件,对ServerSocketChannnel可以是CONNECT事件,对SocketChannel可以是READ、WRITE、CLOSE事件等。
          事件处理器(Event Handler): 定义事件处理方法,以供Initialization Dispatcher回调使用。
          对于Reactor模式,可以将其看做由两部分组成,一部分是由Boss组成,另一部分是由worker组成。Boss就像老板一样,主要是拉活儿、谈项目,一旦Boss接到活儿了,就下发给下面的work去处理。也可以看做是项目经理和程序员之间的关系。
1、概念
      reactor设计模式,是一种基于事件驱动的设计模式。Reactor框架是ACE各个框架中最基础的一个框架,其他框架都或多或少地用到了Reactor框架。
      在事件驱动的应用中,将一个或多个客户的服务请求分离(demultiplex)和调度(dispatch)给应用程序。在事件驱动的应用中,同步地、有序地处理同时接收的多个服务请求。
      reactor模式与外观模式有点像。不过,观察者模式与单个事件源关联,而反应器模式则与多个事件源关联 。当一个主体发生改变时,所有依属体都得到通知。
2、优点
       1)响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的;
       2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;
       3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;
       4)可复用性,reactor框架本身与具体事件处理逻辑无关,具有很高的复用性;
3、缺点
      1)相比传统的简单模型,Reactor增加了一定的复杂性,因而有一定的门槛,并且不易于调试。
      2)Reactor模式需要底层的Synchronous Event Demultiplexer支持,比如Java中的Selector支持,操作系统的select系统调用支持,如果要自己实现Synchronous Event Demultiplexer可能不会有那么高效。
      3) Reactor模式在IO读写数据时还是在同一个线程中实现的,即使使用多个Reactor机制的情况下,那些共享一个Reactor的Channel如果出现一个长时间的数据读写,会影响这个Reactor中其他Channel的相应时间,比如在大文件传输时,IO操作就会影响其他Client的相应时间,因而对这种操作,使用传统的Thread-Per-Connection或许是一个更好的选择,或则此时使用Proactor模式。

3.Java 9 带来了怎样的新功能        参考链接            参考链接

1. Java 平台级模块系统
2. Linking:
    可以创建针对应用程序进行优化的最小运行时映像而不需要使用完全加载 JDK 安装版本。
3. JShell :
    交互式 Java编程环境
4. 改进的 Javadoc
5. 集合工厂方法:
    如:Set<Integer> ints = Set.of(1, 2, 3);List<String> strings = List.of("first", "second");
6. 改进的 Stream API:
    Stream 接口中添加了 4 个新的方法:iterate,dropWhile,takeWhile,ofNullable。
    DropWhile丢弃Stream的第一个项目,直到满足条件。
    TakeWhile处理项目直到满足条件。
    Iterate允许使用Stream为for循环写入适当的替换。它需要Stream的初始值,定义何时停止迭代的条件和生成下一个元素的步骤函数。
    OfNullable作为名称建议让你从对象创建Stream,而不需要检查null。它返回一个包含单个元素的顺序Stream,如果非空,则返回一个空的Stream。
7. 私有接口方法
    私有接口方法将不会成为你API的一部分
8. HTTP/2
    Java 9将完全支持HTTP 2.0,并为Java提供了一个新的HTTP客户端,它将替代仅适用于blocking模式的HttpURLConnection – 每对请求/响应有一个线程,这增加了延迟和加载时间的网页。HTTP客户端还提供API来处理HTTP和服务器推送等HTTP功能。
9. 多版本兼容 JAR
    当一个新版本的 Java 出现的时候,你的库用户要花费数年时间才会切换到这个新的版本。这就意味着库得去向后兼容你想要支持的最老的 Java 版本 (许多情况下就是 Java 6 或者 7)。这实际上意味着未来的很长一段时间,你都不能在库中运用 Java 9 所提供的新特性。幸运的是,多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本:
10.增强处理API
    新版本将扩展与操作系统进行交互的能力。将添加新的方法来处理PID管理,进程名称和状态,子进程管理等等。

4.Java 与 C++ 对比,C++ 或 Java 中的异常处理机制的简单原理和应用

C++:
在C的时候,错误处理要 setjmp() / longjmp() 通过。而C++里, setjmp() / longjmp() 已经不能用了。C++的异常可以是类,也可以是基本类型(如int)。在标准库中,也存在exception类。但是,C++并没有要求我们自定义的异常要继承某个类。
JAVA:
当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。
违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。
所有的异常都是java.lang.Thowable的子类。

5.简单讲讲 Tomcat 结构,以及其类加载器流程            参考链接    参考链接        

1.tomcat结构图 
这里写图片描述

2.结构描述 
2.1 Server:一个catalina服务器 
2.2 Service:服务,负责处理所有Connector所获得的客户请求。由多个Connector和一个Engine组成。 
2.3 Connector:连接器,负责在指定端口上监听请求,并将获得的请求交给Engine来处理,从Engine处获得回应并返回客户。Tomcat默认有两个连接器:1.监听http请求的连接器;2.监听ajp请求的连接器。 
2.4 Engine:顶层容器。Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名。 
当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理。 
Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理。 
2.5 Host:它是Engine的子容器,代表一个Virtual Host,虚拟主机,每个虚拟主机和某个网络域名Domain Name相匹配。

每个虚拟主机下都可以部署(deploy)一个或者多个Web App,每个Web App对应于一个Context,有一个Context path。

当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理。

匹配的方法是“最长匹配”,所以一个path==""的Context将成为该Host的默认Context。

所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配。

2.6 Context:它是Host的子容器,一个Context对应于一个Web Application,一个Web Application由一个或者多个Servlet组成。

Context在创建的时候将根据配置文件$CATALINA_HOME$/conf/web.xml和$WEBAPP_HOME$/WEB-INF/web.xml载入Servlet类。

当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类。

如果找到,则执行该类,获得请求的回应,并返回。

2.7 Wrapper:它是针对每个Servlet的Container,是Context的子容器。每个Servlet都有相应的Wrapper来管理。 
综上,可以看出Server、Service、Connector、Container、Engine、Host、Context和Wrapper这些核心组件的作用范围是逐层递减,并逐层包含。

3.启动过程 
3.1 设置Catalina (Tomcat Servlet 容器的代号)的路径:CATALINA_HOME 和CATALINA_BASE 
3.2 初始化Tomcat 的类加载器体系 
3.3 创建org.apache.catalina.startup.Catalina 对象(启动阶段剩余的工作由Catalina类 完成) 
3.4 初始化Container和Connector。其实就是解析server.xml并将其中对象都实例化起来。 
3.5 启动Container和Connector。 
跟初始化的顺序一样,先启动所有的Container,然后启动Connector。 Tomcat默认Connector有两个:Http11Protocol和AjpProtocol。 
这两种默认Connector都使用JIoEndpoint处理传入的TCP连接,是代码里写死的。 
所以如果想使用NioEndpoint,就要在server.xml配置时使用Http11NioProtocol或AjpNioProtocol.(Connector属性protocol=”类全名”即可) 
无论使用哪种Endpoint,其启动时都主要是启动这三个线程:Acceptor、Executor和AsyncTimeout线程。 
3.5.1 Connector的start方法的最后,会根据已经加载完毕的容器的结构关系,构造出Mapper。供以后请求来临时的定位使用。 
(由于先启动了Acceptor,后构造的Mapper,所以在构造出Mapper之前,Acceptor启动了也没意义,因为请求来了也找不到对应的context,不过这倒也没关系,等启动全完了再发请求就行了) 
3.6 至此,启动完毕,处于等待请求的状态。

4.请求过程 
4.1 浏览器发起请求 
4.2 Acceptor接收到请求。 
4.3 如果是jioEndpoint处理: 
4.3.1 放到线程池执行。getExecutor().execute(new SocketProcessor(wrapper)); 
4.3.2 执行内容根据当前Connector协议的不同而不同。如果是http11则执行Http11Processor,Ajp则执行AjpProcessor。 
4.3.3 如果是Http11Processor处理: 
4.3.3.1 首先,获取请求方法,请求的URI和协议名称及版本。 
4.3.3.2 调用adapter.service。这里的adapter是Connector初始化时set进来的。默认的也是代码写死的CoyoteAdapter。如果使用自己定义的连接器,就可以重写初始化方法,从而使用另外的adapter了。 
4.3.3.3 CoyoteAdapter的service方法中,先构造并填充request对象,然后根据mapper的内容,对request所指向的请求context和wrapper进行定位。 
4.3.3.4 定位之后,调用容器的invoke方法,这个容器就是StandardEngine,把request传给容器,交给容器处理了。 
4.3.3.5 request传给容器,由于容器是个层次结构,所以应该先由最顶层容器开始,这样才能够准确找到并按正确顺序执行处理。 
4.3.3.6 设置响应头信息并把response输出给客户端的方法是: AbstractHttp11Processor.endRequest()。

5.部署流程

5.1 首先,热加载线程ContainerBackgroundProcessor一直在运行着,监控着 
5.1.1 StandardHost会一直发出一个代号为periodic的事件,该事件处理中调用HostConfig.check方法。所以这里就是周期性的check 
5.2 HostConfig.check方法内容: 
5.2.1 check所有已部署的应用。当check出一个context不存在了时,就调用host.removeChild(context)。 
5.2.1.1 逐层的stop:context.stop,wrapper.stop。调用context.stop时,会触发删除其所有的wrapper.stop。 
5.2.1.2 mapperlistener会接收到removeChild事件。从而与context(及其wrapper)解除绑定。 
5.2.2 热加载未部署的应用。当检查出有一个新的context.xml需要deploy时,会new一个DeployDescriptor放到线程池执行。 
该线程会调用HostConfig.deployDescriptor: 
5.2.2.1 利用digester对context.xml进行解析,得到context实例。 
5.2.2.2 把xml和最后修改时间标记到deployedApp.redeployResources 
5.2.2.3 host.addChild(context);——方法中会调用该context的start,从而启动其所有的wrapper。 
5.2.2.4 mapperlistener也会接收到addChild事件。从而与context(及其wrapper)绑定。

Tomcat类加载

当tomcat启动时,会创建几种类加载器:

1 Bootstrap 引导类加载器 + Extension类加载器

    先尝试在Bootstrap(位于jre/lib/rt.jar下)和Extension(位于jre/lib/ext下)中进行类型加载。

2 System 系统类加载器(仅仅tomcat使用)

    加载tomcat启动的类,比如CATALINA_HOME/bin/bootstrap.jar,通常在catalina.sh中指定。位于CATALINA_HOME/bin下。

3 Common 通用类加载器(tomcat,web程序都可以使用)

    加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar

4 webapp 应用类加载器(仅仅web程序都可以使用)

    每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于WEB-INF/lib下的jar文件中的class和WEB-INF/classes下的class文件。

Tomcat 类加载顺序

    1 使用bootstrap引导类加载器加载(e.g. JRE中的Java基础包)

    2 使用system系统类加载器加载 (e.g. CATALINA_HOME/bin/bootstrap.jar)

    3 使用应用类加载器在WEB-INF/classes中加载

    4 使用应用类加载器在WEB-INF/lib中加载 

    5 使用common类加载器在CATALINA_HOME/lib中加载

    (e.g. CATALINA_HOME/lib/下的)

6.虚拟内存是什么
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。
注意:虚拟内存不只是“用磁盘空间来扩展物理内存”的意思——这只是扩充内存级别以使其包含硬盘驱动器而已。把内存扩展到磁盘只是使用虚拟内存技术的一个结果,它的作用也可以通过覆盖或者把处于不活动状态的程序以及它们的数据全部交换到磁盘上等方式来实现。对虚拟内存的定义是基于对地址空间的重定义的,即把地址空间定义为“连续的虚拟内存地址”,以借此“欺骗”程序,使它们以为自己正在使用一大块的“连续”地址。

7.阐述下 SOLID 原则
在 程序设计领域, SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期[1] 引入的记忆术首字母缩略字[2][3],指代了面向对象编程和面向对象设计的五个基本原则。当这些原则被一起应用时,它们使得一个程序员开发一个容易进行软件维护和扩展的系统变得更加可能。[1] SOLID所包含的原则是通过引发编程者进行软件源代码的代码重构进行软件的代码异味清扫,从而使得软件清晰可读以及可扩展时可以应用的指南。SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。[1][4]
首字母指代概念
S单一功能原则认为对象应该仅具有一种单一功能的概念。
O开闭原则认为“软件体应该是对于扩展开放的,但是对于修改封闭的”的概念。
L里氏替换原则认为“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”的概念。

参考契约式设计

I接口隔离原则认为“多个特定客户端接口要好于一个宽泛用途的接口”[5] 的概念。
D依赖反转原则认为一个方法应该遵从“依赖于抽象而不是一个实例”[5] 的概念。
依赖注入是该原则的一种实现方式。
8.请简要讲一下你对测试驱动开发(TDD)的认识
测试驱动开发(英语:Test-driven development,缩写为TDD)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。
测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
正面评价
可以有效的避免过度设计带来的浪费。但是也有人强调在开发前需要有完整的设计再实施可以有效的避免重构带来的浪费。
可以让开发者在开发中拥有更全面的视角。
负面评价
开发者可能只完成满足了测试的代码,而忽略了对实际需求的实现。有实践者认为用结对编程的方式可以有效的避免这个问题。
会放慢开发实际代码的速度,特别对于要求开发速度的原型开发造成不利。这里需要考虑开发速度需要包含功能和品质两个方面,单纯的代码速度可能不能完全代表开发速度。
对于GUI,资料库和Web应用而言。构造单元测试比较困难,如果强行构造单元测试,反而给维护带来额外的工作量。有开发者认为这个是由于设计方法,而不是开发方法造成的困难。
使得开发更为关注用例和测试案例,而不是设计本身。目前,对于这个观点有较多的争议。
测试驱动开发会导致单元测试的覆盖度不够,比如可能缺乏边界测试。在实际的操作中,和非测试驱动开发一样,当代码完成以后还是需要补充单元测试,提高测试的覆盖度。

9.CDN实现原理
在描述CDN的实现原理,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别:
用户提交域名→浏览器对域名进行解释→得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复
由上可见, 用户访问未使用CDN缓存网站的过程为:
1)、用户向浏览器提供要访问的域名;
2)、浏览器调用域名解析函数库对域名进行解析,以得到此域名对应的IP地址;
3)、浏览器使用所得到的IP地址,向域名的服务主机发出数据访问请求;
4)、浏览器根据域名主机返回的数据显示网页的内容。
通过以上四个步骤,浏览器完成从用户处接收用户要访问的域名到从域名服务主机处获取数据的整个过程。CDN网络是在用户和服务器之间增加Cache层,如何将用户的请求引导到Cache上获得源服务器的数据,主要是通过接管DNS实现,下面让我们看看访问使用CDN缓存后的网站的过程:

通过上图,我们可以了解到, 使用了CDN缓存后的网站的访问过程变为
1)、用户向浏览器提供要访问的域名;
2)、浏览器调用域名解析库对域名进行解析,由于CDN对域名解析过程进行了调整,所以解析函数库一般得到的是该域名对应的CNAME记录,为了得到实际IP地址,浏览器需要再次对获得的CNAME域名进行解析以得到实际的IP地址;在此过程中,使用的全局负载均衡DNS解析,如根据地理位置信息解析对应的IP地址,使得用户能就近访问。
3)、此次解析得到CDN缓存服务器的IP地址,浏览器在得到实际的IP地址以后,向缓存服务器发出访问请求;
4)、缓存服务器根据浏览器提供的要访问的域名,通过Cache内部专用DNS解析得到此域名的实际IP地址,再由缓存服务器向此实际IP地址提交访问请求;
5)、缓存服务器从实际IP地址得得到内容以后,一方面在本地进行保存,以备以后使用,另一方面把获取的数据返回给客户端,完成数据服务过程;
6)、客户端得到由缓存服务器返回的数据以后显示出来并完成整个浏览的数据请求过程。
通过以上的分析我们可以得到,为了实现既要对普通用户透明(即加入缓存以后用户客户端无需进行任何设置,直接使用被加速网站原有的域名即可访问,又要在为指定的网站提供加速服务的同时降低对ICP的影响,只要修改整个访问过程中的域名解析部分,以实现透明的加速服务,下面是 CDN网络实现的具体操作过程。
1)、作为ICP,只需要把域名解释权交给CDN运营商,其他方面不需要进行任何的修改;操作时,ICP修改自己域名的解析记录,一般用cname方式指向CDN网络Cache服务器的地址。
2)、作为CDN运营商,首先需要为ICP的域名提供公开的解析,为了实现sortlist,一般是把ICP的域名解释结果指向一个CNAME记录;
3)、当需要进行sortlist时,CDN运营商可以利用DNS对CNAME指向的域名解析过程进行特殊处理,使DNS服务器在接收到客户端请求时可以根据客户端的IP地址,返回相同域名的不同IP地址;
4)、由于从cname获得的IP地址,并且带有hostname信息,请求到达Cache之后,Cache必须知道源服务器的IP地址,所以在CDN运营商内部维护一个内部DNS服务器,用于解释用户所访问的域名的真实IP地址;
5)、在维护内部DNS服务器时,还需要维护一台授权服务器,控制哪些域名可以进行缓存,而哪些又不进行缓存,以免发生开放代理的情况。

10.Maven 和 ANT 有什么区别        参考链接

略,看参考链接吧

11.UML中有哪些常用的图

用例图(use case diagram)、类图(class diagram)、时序图(sequence diagram)、协作图(collaboration diagram)、状态图(statechart diagram)、活动图(activity diagram)、构件图(component diagram)、部署图(deployment diagram)等。
三种图最为重要,分别是:
    用例图(用来捕获需求,描述系统的功能,通过该图可以迅速的了解系统的功能模块及其关系)、
    类图(描述类以及类与类之间的关系,通过该图可以快速了解系统)、
    时序图(描述执行特定任务时对象之间的交互关系以及执行顺序,通过该图可以了解对象能接收的消息也就是说对象能够向外界提供的服务)。

12.Linux 下 IO 模型有几种,各自的含义是什么。    参考链接        参考链接

    阻塞IO(blocking IO)    
    非阻塞IO (nonblocking IO)
    IO复用(select 和poll) (IO multiplexing)
    信号驱动IO (signal driven IO (SIGIO))
    异步IO (asynchronous IO (the POSIX aio_functions))
前四种都是同步,只有最后一种才是异步IO。

13.Linux 系统下你关注过哪些内核参数,说说你知道的        参考链接

更多可查看参考链接
下列文件所在目录:
/proc/sys/net/ipv4/

名称

默认值

建议值

描述

tcp_syn_retries

5

1

对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1决定的)

tcp_synack_retries

5

1

对于远端的连接请求SYN,内核会发送SYN ACK数据报,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里决定内核在放弃连接之前所送出的 SYN+ACK 数目。不应该大于255,默认值是5,对应于180秒左右时间。

tcp_keepalive_time

7200

600

TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。

防止两边建立连接但不发送数据的攻击。

tcp_keepalive_probes

9

3

TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。

tcp_keepalive_intvl

75

15

探测消息未获得响应时,重发该消息的间隔时间(秒)。默认值为75秒。 (对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值)

tcp_retries1

3

3

放弃回应一个TCP连接请求前﹐需要进行多少次重试。RFC 规定最低的数值是3

tcp_retries2

15

5

在丢弃激活(已建立通讯状况)TCP连接之前﹐需要进行多少次重试。默认值为15,根据RTO的值来决定,相当于13-30分钟(RFC1122规定,必须大于100).(这个值根据目前的网络设置,可以适当地改小,我的网络内修改为了5)

tcp_orphan_retries

7

3

在近端丢弃TCP连接之前﹐要进行多少次重试。默认值是7个﹐相当于 50 - 16分钟﹐视RTO 而定。如果您的系统是负载很大的web服务器﹐那么也许需要降低该值﹐这类 sockets 可能会耗费大量的资源。另外参的考tcp_max_orphans(事实上做NAT的时候,降低该值也是好处显著的,我本人的网络环境中降低该值为3)

tcp_fin_timeout

60

2

对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒。

tcp_max_tw_buckets

180000

36000

系统在同时所处理的最大 timewait sockets 数目。如果超过此数的话﹐time-wait socket 会被立即砍除并且显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)(事实上做NAT的时候最好可以适当地增加该值)


14.Linux 下用一行命令查看文件的最后五行
tail -n 5 filename
15.平时用到哪些 Linux 命令
ls,grep,tail,cat,ps,find,curl,top,ztop,iotop,vim,mv,mkdir,sh
16.用一行命令输出正在运行的 Java 进程
ps aux | grep java
17.使用什么命令来确定是否有 Tomcat 实例运行在机器上
ps aux | grep tomcat    或使用tomcat stauts命令
18.什么是 N+1 难题    参考链接
执行一条select语句查询当前表,执行N条语句查询与当前表关联的表,N是不同的关联数。效率很差
可以使用join解决

19.什么是 paxos 算法    参考链接
看参考链接吧,太复杂了

20.什么是 restful,讲讲你理解的 restful        参考链接

restful:

一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

如何理解restful:
REST 这个词其实是 Representational State Transfer 的缩写 翻译过来就是表现性状态转换
其实 REST 是指的 资源的表示性状态转换。然后简单的对这几个词做一个解释
资源(Resources)网络上可以访问的资源,典型的就是一段URI
表现性(Representational):资源的表现形式,比如html json xml 等等
状态转换(State Transfer):原本Http是一个无状态协议,但是访问一个网站是一个互动的过程,通过某种手段使服务端发生状态的转换,同时这种转换时建立在表现性之上的。所以是 Representational State Transfer

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

restful的总结
每一个URI代表一种资源;
客户端和服务器之间,传递这种资源的某种表现层(Representation);
客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。
21.什么是 zab 协议        参考链接更详细
  ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息广播协议) 是zookeeper数据一致性的核心算法
  ZAB 协议并不像 Paxos 算法那样,是一种通用的分布式一致性算法,它是一种特别 为 ZooKeeper 设计的崩溃可恢复的原子消息广播算法
    ZAB协议主要实现了:
  1.使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用 ZAB 的原子广播协议,将服务器数据的状态变更以事务 Proposal 的形式广播到所有的副本进程上去。
  2.保证一个全局的变更序列被顺序应用。
  ZooKeeper是一个树形结构,很多操作都要先检查才能确定能不能执行,比如P1的事务t1可能是创建节点“/a”,t2可能是创建节点“/a/aa”,只有先创建了父节点“/a”,才能创建子节点“/a/aa”。为了保证这一点,ZAB要保证同一个leader的发起的事务要按顺序被apply,同时还要保证只有先前的leader的所有事务都被apply之后,新选的leader才能在发起事务。
  3.当前主进程出现异常情况的时候,依旧能够正常工作。
   ZAB 协议的核心:定义了事务请求的处理方式。
  所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为 Leader服务器,而余下的其他服务器则成为 Follower 服务器。 Leader 服务器负责将一个客户端事务请求转换成一个事务proposal(提议),并将该 Proposal分发给集群中所有的Follower服务器。之后 Leader 服务器需要等待所有Follower 服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么 Leader 就会再次向所有的 Follower服务器分发Commit消息,要求其将前一个proposal进行提交。
  这种事务处理方式与2PC(两阶段提交协议)区别在于,两阶段提交协议的第二阶段中,需要等到所有参与者的"YES"回复才会提交事务,只要有一个参与者反馈为"NO"或者超时无反馈,都需要中断和回滚事务。
   ZAB协议介绍:
  ZAB 协议包括两种基本的模式,分别是崩溃恢复和消息广播。
  当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时, ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的Leader 服务器同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。
  当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。当一台同样遵守 ZAB 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个 Leader 服务器在负责进行消息广播 , 那么新加人的服务器就会自觉地进人数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。
22.什么是领域模型(domain model)?贫血模型(anaemic domain model) 和充血模型(rich domain model)有什么区别    参考链接

领域模型是领域内的概念类或现实世界中对象的可视化表示,又称为概念模型或分析对象模型,它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。

贫血模型是指使用的领域对象中只有setter和getter方法(POJO),所有的业务逻辑都不包含在领域对象中而是放在业务逻辑层。有人将我们这里说的贫血模型进一步划分成失血模型(领域对象完全没有业务逻辑)和贫血模型(领域对象有少量的业务逻辑),我们这里就不对此加以区分了。

充血模型将大多数业务逻辑和持久化放在领域对象中,业务逻辑(业务门面)只是完成对业务逻辑的封装、事务和权限等的处理。下面两张图分别展示了贫血模型和充血模型的分层架构。

贫血模型

这里写图片描述

充血模型

这里写图片描述

贫血模型下组织领域逻辑通常使用事务脚本模式,让每个过程对应用户可能要做的一个动作,每个动作由一个过程来驱动。也就是说在设计业务逻辑接口的时候,每个方法对应着用户的一个操作,这种模式有以下几个有点:

- 它是一个大多数开发者都能够理解的简单过程模型(适合国内的绝大多数开发者)。

- 它能够与一个使用行数据入口或表数据入口的简单数据访问层很好的协作。

- 事务边界的显而易见,一个事务开始于脚本的开始,终止于脚本的结束,很容易通过代理(或切面)实现声明式事务。

然而,事务脚本模式的缺点也是很多的,随着领域逻辑复杂性的增加,系统的复杂性将迅速增加,程序结构将变得极度混乱。开源中国社区上有一篇很好的译文《贫血领域模型是如何导致糟糕的软件产生》对这个问题做了比较细致的阐述。


23.什么是领域驱动开发(Domain Driven Development)

什么是领域驱动开发

将问题抽象为一个领域解决方案。并针对此领域(即抽象)进行开发的方式。

领域驱动开发解决了什么问题

解决两个问题1,变化。2,复杂度。

原则上适用于任何软件,特别适用于一些特别复杂,变化特别频繁的系统——尤其是迭代很快又很复杂的稳定要求又很高的互联网金融核心系统。

在这些业务系统中,常常糅合了支付,账务,会计等多业务领域的知识;同时糅合了通讯,协议,安全,编码等多种技术领域知识;如果涉及到多系统对接,甚至还要常常面临多种不同的解决方案的整合。

怎么办?

1,问题分层,转化为业务领域,技术领域。通过协议或者接口先屏蔽技术上的差异性。各层只关注自己的问题。

2,问题分块,同层问题转化为A,B,C等不同业务领域;定义他们彼此服务整合的方式。

3,关注要素,忽略细节 ;关注抽象,忽略具体;……

————————其实就是分而治之,化繁为简;抓住主要矛盾的过程。

领域驱动开发的威力

领域模型的核心是抽象和分治(less is more)

例子1:linux很神奇的管道的原理么(命令通过|无限组装)?

1,任何io操作都是文件

2,任何文件有三个默认io方向(stdin,stdout,stderror)

3,pipe的作用是链接上下文件,转化stdout stdin

ls *|grep abc 的底层原理就是

ls * (输出到stdout) (转化上一个的stdout为下一个的stdin) grep abc( 从stdin)

顺便说一下 不单单你看到的文件 linux下几乎啥都是file(命令,设备……),你想想这样玩的威力吧

再说一下应对复杂度的威力,说一下金融届有名的三户模型

卡客账,卡即支付工具的抽象,客即人的抽象,账即资金的抽象。

1,存折换成卡,卡换成app,核心不需要任何变动

2,红包,优惠券,信贷账户怎么玩?其实就是账户之间增加父子结构而已。

(红包,优惠券,信贷账户特征是有额度;但都是假的,真实发生交易的时候才操作真实资金账户;其他情况下不作为资金处理:解决方案就是设置父子账户,子账户即使红包信贷账户,对子账户的操作实际操作的是户账户资金。不需要开发)

这三户模型的抽象,也有助于解决金融产品一些快速的创新和复杂的产品设计——前提是开发和产品理解这个抽象,我真见过再设计一大套红包,信贷账户表,搞一大堆专门处理他们逻辑差异性的金融系统——这样就导致整天忙死了,并且问题不断。

人的抽象在支付上用处不大,但是在风控上意义重大。风控的本质上就是对人的理解和博弈。不论啥卡欺诈,账户欺诈,设备……最终都是要挂到这个概念上的,不论任何规则,模型,也最终都要落实到这个模型上的。

卡客账:金融业务和金融风险的完美建模有没有。

领域模型开发要注意那些

  1. 领域划分,定义
  2. 概念定义
  3. 概念职责,行为,服务
  4. 概念之间关系
  5. 应对变化
24.介绍一下了解的 Java 领域的 Web Service 框架
略,浪费时间
25.Web Server、Web Container 与 Application Server 的区别是什么

Web Server:Web server 是指能够接收,解析,处理HTTP请求,并将处理后的结果返回给合适的客户端(比如浏览器)的服务器。例如IHS(IBM HTTP Server)和Apache,IHS是建立在Apahce之上的由IBM添加更多功能后的服务器,都处理HTTP请求(正如IHS名字所显示的 http server)
Web Container:Web容器J2EE标准的实现,为serverlet和jsp提供运行环境。例如,当一个HTTP请求通过要访问一个web组件(通常是一个serverlet或者是jsp),通常是将这个请求转发给web container处理完毕后再返回到web server。Tomcat是一个轻量级的web container。
Application Server: 是一个完整的server,它提供整个业务模块 (EJBs,ADFs,etc)运行的环境。除了单独作为一个web container外,它还能处理HTTP请求(当然包括其它协议,比如tcp,消息队列等)。Websphere 和weblogic 都属于此类

26.微服务(MicroServices)与巨石型应用(Monolithic Applications)之间的区别在哪里

不造

27.描述 Cookie 和 Session 的作用,区别和各自的应用范围,Session工作原理

写完保存失败,不写了。

28.你常用的持续集成(Continuous Integration)、静态代码分析(Static Code Analysis)工具有哪些

jekins,soner还有阿里代码规约插件

29.简述下数据库正则化(Normalizations)
不造
30.KISS,DRY,YAGNI 等原则是什么含义    参考链接

原则1:不做重复的事(Don't Repeat Yourself)
原则2:保持简单直接(Keep it Simple Stupid)
原则3:你不需要它(You Ain’t Gonna Need It)

31.分布式事务的原理,优缺点,如何使用分布式事务?   参考链接

还是看参考链接吧,晚上资料有的是。

32.布式集群下如何做到唯一序列号        snowflake链接

数据库自增id;每个服务器一个id,订单号包含服务器id;zookeeper;最好的是facebook的snowflake

33.Http请求头都有哪些,分别是什么意思    参考链接


34.http请求结构,分别是什么   参考链接

HTTP请求报文
请求行、请求头部、空行、请求数据

这里写图片描述

 

 

这里写图片描述

HTTP响应报文:
响应行、响应头、响应体

这里写图片描述

35.HTTPS 的加密方式是什么,讲讲整个加密解密流程

对称密钥和非对称密钥方式,RSA和DES。过程我都熟悉,就不写了偷笑

36.HTTPS和HTTP的区别

在应用层(http)和传输层(tcp)间加了一层会话层(SSL)
在URL前加https://前缀表明是用SSL加密的。 你的电脑与服务器之间收发的信息传输将更加安全。
Web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。http的连接很简单,是无状态的,...
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议
要比http协议安全

37.HTTP连接池实现原理    参考链接


38.HTTP集群方案

感觉问的是负载均衡,Nginx、一致性hash,差不多吧

39.Nginx、lighttpd、Apache三大主流 Web服务器的区别    参考链接

这里写图片描述

40.是否看过框架的一些代码


41.持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些

略,看个人了

42.数值提升是什么    参考链接

数字类型提升机制被用于算术运算符上,通常使用场景为:

  • 同一类型转换 
    虽然并无什么作用,但有时可以使代码更清晰。
  • 拓宽原始类型转换 
    指byte、short、int、long、float、double由低向高转换。
  • 自动拆箱转换 
    基础类型引用类的拆箱方法,如r.intValue()
43.你能解释一下里氏替换原则吗    参考链接

任何基类可以出现的地方,子类一定可以出现

44.你是如何测试一个应用的?知道哪些测试框架


45.传输层常见编程协议有哪些?并说出各自的特点    参考链接

TCP协议:面向连接的可靠传输协议。利用TCP进行通信时,首先要通过三步握手,以建立通信双方的连接。TCP提供了数据的确认和数据重传的机制,保证发送的数据一定能到达通信的对方。

UDP协议:是无连接的,不可靠的传输协议。采用UDP进行通信时不用建立连接,可以直接向一个IP地址发送数据,但是不能保证对方是否能收到






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值