软件开发工程师进阶之路

服务器方面:

1、web服务器nginx和apache的对比分析

①nginx相对于apache的优点:

轻量级,同样起web 服务,比apache 占用更少的内存及资源 ,抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能,高度模块化的设计,编写模块相对简单。

apache相对于nginx 的优点:A.rewrite ,比nginx 的rewrite 强大;B.动态页面,模块超多,基本想到的都可以找到;C.少bug ,nginx 的bug 相对较多;D.超稳定.

一般来说,需要性能的web 服务,用nginx 。如果不需要性能只求稳定,那就apache.

②作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率。Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多.

③Nginx 配置简洁,Apache 复杂。Nginx 静态处理性能比 Apache 高 3倍以上,Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端用。Apache 的组件比 Nginx 多,现在 Nginx 才是Web 服务器的首选。

④最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程。

⑤nginx处理静态文件好,耗费内存少.但无疑apache仍然是目前的主流,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式。

⑥nginx处理动态请求是鸡肋,一般动态请求要apache去做,nginx只适合静态和反向。

⑦Nginx优于apache的主要两点:A.Nginx本身就是一个反向代理服务器 B.Nginx支持7层负载均衡;其他的当然,Nginx可能会比 apache支持更高的并发。

数据库方面:

1、数据库优化:

①方法:MySQL可以建分表,读写分离,建索引,一般经常更新的字段不适合建索引,建索引会降低数据非查询操作的效率。主键是一种特殊的索引。

②导致索引失效的情况:

A、如果条件中有or,即使其中有条件带索引也不会使用到。

B、对于多列索引,不是使用的第一部分,则不会使用索引。

C、like查询是以%开头,而不是以%结尾的。

D、如果索引列类型是字符串,一定要在条件中将数据使用引号引用起来,否则不使用索引。

E、如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

2、MySQL引擎的种类和区别

①种类:MyISAM、InnoDB、MEMORY、MERGE、Archive、Blackhole、CSV、Federate、Merge、NDB集群引擎,第三方引擎:OLTP类引擎、面向列的存储引擎、社区存储引擎。

②区别:

A、MyISAM是MySQL5.1及之前的默认存储引擎。MyISAM不支持事务、也不支持外键,但其访问速度快,对事务完整性没有要求。MyISAM表还支持3中不同的存储格式:

1 静态表

2 动态表

3 压缩表

B、InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是比起MyISAM存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。 InnoDB存储方式为两种:1 使用共享表空间存储 2 使用多表空间

C、MEMORY存储引擎使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH索引。但是一旦服务关闭,表中的数据就会丢失掉。

D、MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同。MERGE表本身没有数据,对MERGE类型的表进行查询、更新、删除的操作,就是对内部的MyISAM表进行的。

3、数据库事务

(1)四个特性:ACID,原子性,一致性,隔离性,持久性。

(2)四个隔离级别:

√: 可能出现    ×: 不会出现

  脏读 不可重复读 幻读
Read uncommitted
Read committed ×
Repeatable read × ×
Serializable × × ×

Read Uncommitted(读取未提交内容)
       在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)
       这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)
       这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
Serializable(可串行化)
       这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:
i.   脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
ii.  不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
iii. 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

(3)一致性处理: 

A、开启事务。B、申请写权限,也就是给对象(表或记录)加锁。C、假如失败,则结束事务,过一会重试。D、假如成功,也就是给对象加锁成功,防止其他用户再用同样的方式打开。E、进行编辑操作。F、写入所进行的编辑结果。G、假如写入成功,则提交事务,完成操作。 H、假如写入失败,则回滚事务,取消提交。I、(G、H)两步操作已释放了锁定的对象,恢复到操作前的状态。

(4)基于事务的数据库引擎的选型:如果考虑到事务,推荐选用MySQL INNODB引擎;如果考虑速度,建议考虑MySQL MyISAM引擎,并且需要在代码层面做比较复杂的处理,如通过多线程、异步、非阻塞等方式对数据库进行清理,同时需要信号量、栏栅、数据库标志位等工具保证数据一致性。

4、海量数据处理

(1)数据库扩展:

①纵向扩展:基于业务的高度隔离性和数据的安全性,对业务和数据进行合理的切分,进行主-备机分离,主-主同步,主-从同步(对于MySQL数据库是单向异步同步机制),主-从热备等操作。

②横向扩展:对数据表进行横向切分,按一定的规则(hash取模分、user_id尾数、自定义算法等)对数据表进行横向切分。

关于数据库架构和扩展方面的文章请见:Mysql在大型网站的应用架构演变

(2)分布式数据方案:

①提供分库规则和路由规则(RouteRule简称RR),将上面的说明中提到的三中切分规则直接内嵌入本系统,具体的嵌入方式在接下来的内容中进行详细的说明和论述; 

②引入集群(Group)的概念,保证数据的高可用性; 

③引入负载均衡策略(LoadBalancePolicy简称LB); 

④引入集群节点可用性探测机制,对单点机器的可用性进行定时的侦测,以保证LB策略的正确实施,以确保系统的高度稳定性; 

⑤引入读/写分离,提高数据的查询速度。

具体描述请参见博文:MySQL 海量数据的存储和访问解决方案

(3)数据库切分策略介绍,请见博文:数据库Sharding的基本思想和切分策略

(4)随着数据量随着业务的发展不断增大,传统的关系型数据库RDB已经无法满足需要,这时需要引入新的海量数据处理解决方案:Apache HBase。

框架方面:

Spring原理(建议读一下框架核心源码)

①IoC(Inversion of control): 控制反转,依赖注入

1)IoC:

概念:控制权由对象本身转向容器;由容器根据配置文件去创建实例并创建各个实例之间的依赖关系

2)依赖IoC容器负责管理bean,有两种,一种是BeanFactory,另一种是ApplicationContext,但是ApplicationContext继承与BeanFactory。

核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean

②AOP(Aspect-Oriented Programming): 面向方面编程

1)代理的两种方式:

静态代理:

 针对每个具体类分别编写代理类;

 针对一个接口编写一个代理类;

动态代理:

针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类

2) AOP的主要原理:动态代理

实现:有两种:JDK Proxy和Cglib,Spring规定对于有接口的类用JDK Proxy,对于无接口和抽象类用Cglib,虽然Cglib均可以代理,但是Cglib复杂,效率低。但是Cglib有例外,就是代理的类中不能是final修饰的类或者类中有final方法。

3、Spring、Struts2、Servlet对比

①Servlet原理:Tomcat 的容器等级中,Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,所以 Context 容器如何运行将直接影响 Servlet 的工作方式。

A、Servlet生命周期详解

Servlet的生命周期可以分为四个阶段,即装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段。下面针对每个阶段的编程任务及注意事项进行详细的说明。

B、Servlet创建过程

在默认情况下Servlet实例是在第一个请求到来的时候创建,以后复用。一旦Servlet实例被创建,Web服务器会自动调用init(ServletConfig config)方法来初始化该Servlet。其中方法参数config中包含了Servlet的配置信息,比如初始化参数,该对象由服务器创建。init方法在Servlet生命周期中只执行一次,而且该方法执行在单线程的环境下,因此开发者不用考虑线程安全的问题。

C、服务

一旦Servlet实例成功创建及初始化,该Servlet实例就可以被服务器用来服务于客户端的请求并生成响应。在服务阶段Web服务器会调用该实例的service(ServletRequest request,ServletResponse response)方法,request对象和response对象有服务器创建并传给Servlet实例。request对象封装了客户端发往服务器端的信息,response对象封装了服务器发往客户端的信息。

为了提高效率,Servlet规范要求一个Servlet实例必须能够同时服务于多个客户端请求,即service()方法运行在多线程的环境下,Servlet开发者必须保证该方法的线程安全性。

Serlvet接口只定义了一个服务方法就是service,而HttpServlet类实现了该方法并且要求调用下列的方法之一:

doGet:处理GET请求

doPost:处理POST请求

当发出客户端请求的时候,调用service 方法并传递一个请求和响应对象。Servlet首先判断该请求是GET 操作还是POST 操作。然后它调用下面的一个方法:doGet 或 doPost。如果请求是GET就调用doGet方法,如果请求是POST就调用doPost方法。

②对比:Spring主要有IoC和AOP,Spring中IoC管理的bean为单例模式的,可以配置成原型模式。如果用Spring管理struts2的bean,必须要设置成原型模式,因为struts2封装来了servlet,隔离了servlet的特性,Action不同于Spring,已经是原型模式了。

猜你喜欢

转载自blog.csdn.net/IBLiplus/article/details/84429141