一些项目架构设计

本文章目录

  • 面向对象程序设计的主要原则
    • 1、单一职责原则(Single-Responsibility Principle)
    • 2、里氏代换原则(Liskov Substitution Principle)
    • 3、依赖倒置原则(Dependence Inversion Principle)
    • 4、接口隔离原则(Interface Segregation Principle)
    • 5、迪米特原则(Law of Demeter)
  • 数据库设计原则
    • 范式标准
      • 第一范式:1NF(确保每列保持原子性)
      • 第二范式:2NF(确保表中的每列都和主键相关)
      • 第三范式:3NF (确保每列都和主键列直接相关,而不是间接相关)
  • Nginx (nginx+keepalived保证高可用)
    • Nginx的事件处理
    • Nginx负载均衡算法
  • 秒杀系统
    • IMOOC做法
    • 分布式事务
      • 本地消息表 / 消息事务 - 最终一致性
      • 强一致性
        • 两阶段提交 2PC
        • 三阶段提交 3PC
        • 补偿事务TCC (Try - Confirm - Cancel)
        • 本地消息表
        • 事务消息
  • 用户/项目权限设计
    • ShiroFilter(通过工厂产生过滤器)
  • 数据库性能
    • InnoDB缓存池
    • Mysql查询缓存
    • 持久层缓存
      • Mybatis一级缓存 (会话级别缓存,Session关闭,缓存失效)
      • Mybatis二级缓存 (引入第三方存储机制缓存数据)
  • Linux 常用操作
    • grep (查找文件里符合条件的字符串)
    • find (在指定目录下查找文件)
    • sed (依照脚本的指令来处理、编辑文本文件)
    • awk (文本分析/格式化工具)
    • netstat (显示网络状态)

面向对象程序设计的主要原则

1、单一职责原则(Single-Responsibility Principle)

就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因。所谓职责,我们可以理解为功能,就是设计的这个类功能应该只有一个,而不是两个或更多。也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑撤分这个类了。因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化。
  优点:消除耦合,减小因需求变化引起代码僵化。

2、里氏代换原则(Liskov Substitution Principle)

子类型必须能够替换它们的基类型。一个软件实体如果使用的是一个基类,那么当把这个基类替换成继承该基类的子类,程序的行为不会发生任何变化。软件实体察觉不出基类对象和子类对象的区别。

优点:可以很容易的实现同一父类下各个子类的互换,而客户端可以毫不察觉。

3、依赖倒置原则(Dependence Inversion Principle)

要依赖于抽象,不要依赖于具体,客户端依赖于抽象耦合;抽象不应依赖于细节,细节应依赖于抽象;要针对接口编程,不针对实现编程。
  优点:使用传统过程化程序设计所创建的依赖关系,策略依赖于细节,这是糟糕的,因为策略受到细节改变的影响。依赖倒置原则使细节和策略都依赖于抽象,抽象的稳定性决定了系统的稳定性。

4、接口隔离原则(Interface Segregation Principle)

使用多个专一功能的接口比使用一个的总接口总要好。从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。过于臃肿的接口是对接口的污染,不应该强迫客户依赖于它们不用的方法。

优点:会使一个软件系统功能扩展时,修改的压力不会传到别的对象那里。

如何实现接口隔离原则?
利用委托分离接口;
利用多继承分离接口;

5、迪米特原则(Law of Demeter)

迪米特法则又叫做最少知识原则(Least Knowledge Principle或简写为LKP),就是说,一个对象应当对其他对象有尽可能少的了解,对象与对象之间应使用尽可能少的方法来关联,避免千丝万缕的关系。
  在软件系统中,一个模块设计的好不好的最主要、最重要的标志,就是该模块在多大的程度上将自己的内部数据和其他与实现有关的细节隐藏起来。一个设计好的模块可以将它所有的实现细节隐藏起来,彻底地将提供给外界的API和自己的实现分割开来。这样一来,模块与模块之间就可以仅仅通过彼此的API相互通信,而不理会模块内部的工作细节。这一概念就是“信息的隐藏”,或叫做“封装”,也就是大家熟悉的软件设计的基本教义之一。信息的隐藏非常重要的原因在于,它可以使各个子系统之间脱藕,从而允许它们独立地被开发、优化、使用、阅读以及修改。

数据库设计原则

范式标准

基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。
为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的。

有一张存放商品的基本表,如表1所示。“金额”这个字段的存在,表明该表的设计不满足第三范式,
因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,
可以提高查询统计的速度,这就是以空间换时间的作法。

第一范式:1NF(确保每列保持原子性)

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。

第二范式:2NF(确保表中的每列都和主键相关)

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

第三范式:3NF (确保每列都和主键列直接相关,而不是间接相关)

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。

没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降 低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理
数据模型设计时考虑。降低范式就是增加字段,允许冗余。

Nginx (nginx+keepalived保证高可用)

nginx通过master来接收外界的信号,然后将任务分配给worker去做。比如接受一个nginxup -s reload信号后,交给worker去重启。

  • worker进程:主进程
  • master进程:工作进程

Nginx的事件处理

worker(用了linux的epoll模型)处理方式是异步非阻塞的,当他发现请求1阻塞后,他会去处理请求2;当请求2阻塞后,又会去处理请求3。
一些项目架构设计_第1张图片

Nginx负载均衡算法

  1. 轮询
  2. 权重
  3. IP_hash 保证来自同一ip的请求被打到固定的机器上
  4. least_conn 最少连接方式
  5. fair(第三方) 响应时间方式
  6. url_hash(第三方) 依据URL分配方式

秒杀系统

nginx+keepalived+tomcat开源组件实现应用服务器高可用

你可能感兴趣的:(面试复习,1024程序员节,java)