高级设计和分析技术
动态规划动态规划的本质,是寻找状态的定义,并基于这个定义给出状态转移的方程。
最优子结构(optimal substructure)
定义我们通常要做出一组选择来达到最优解。
在做每个选择的同事,通常会生成与原问题形式相同的子问题。当多于一个选择子集都生成相同的子问题的时候,动态规划通常就会很有效。其关键技术就是对每个这样的子问题都保存其解。档期重复出现时,可避免重复求解。
programming 其实是一种表格法,而非编程。分治法解决的问题是,互不相交的子问题。
最优解有两种: an optimal solution vs the optimal solution。
步骤
刻画一个最优解的结构特征。
递归地定义最优解的值。
计算最优解的值,通过自底向上的方法。
利用计算出的信息,构造一个最优解。
递归是自顶向下求解。迭代可以自底向上求解。
能够用动态规划来解的问题通常具有两个性质:
最有子结构性质:问题的最优解,是由相关子问题的最优解组合而成,而这些子问题可以独立求解。
子问题重叠性质:最优子结构里可能出现的子问题,可能会产生重叠。
切割钢条问题一般形式要做基本的切割分析,得 ...
checklist
写代码 checklist注意位置注意顺序注意初始化注意返回值注意注释注意防御性编程注意数据库性能
上线 checklist代码变更 check 代码配置变更 check 配置系统变更注意上线顺序依赖中间件变更注意配置中间件配置中心配了吗交互所有细节都实现了吗?配监控和埋点数据库变更了吗?安全检查
JDWP 与远程调试
JDWP(Java Debug Wire Protocol),它提供了调试器和目标 JVM (target vm)之间的调试协议。
在 target vm 启动时,增加这个 JAVA_OPTS:
1JAVA_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=26310"
在服务器端,增加 remote debuging 的时候使用如下配置:
12345678# Java 9 以上-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000# Java 5-8-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000# Java 1.4.x -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address= ...
Maven 插件配置指南
本文主要参考了《Guide to Configuring Plug-ins》:
maven 实际上有两种插件:
构建插件,需要在<build/>元素里配置。如<build><pluginManagement/></build>,当然也有<build><plugins/></build>。
报告插件,会在“site generation”里被执行,应该在<reporting/>里配置。如<reporting><plugins/></reporting>。
要引用插件至少要有三个元素:groupId,artifactId, version。
mojo 是什么根据《What is MOJO in Maven?》,mojo 是 Maven plain Old Java Object 的意思。实际上是可执行的 goal。
通用配置一个插件通常包含一个以上的mojo,当一个 mojo 被映射到 goal 的时候,则包含多个 mojo(即一个插件可能有多个 goa ...
Maven 构建生命周期
maven-生命周期.xmind
构建生命周期的基础知识Maven 基于一个“构建生命 周期”的中心概念,也就意味着构建和发布一个特定的工件(也就是工程)的过程已经被清晰地定义了。
有三种内置的生命周期:default,clean 和 site。default 生命周期处理处理项目部署,clean 生命周期处理项目清理,site 生命周期处理项目的站点(site)文档的创建。
实际上这些 lifecycle 只是在(比如 idea 里)对 phase 归类的时候特别有用,我们平时使用 mvn 命令的时候是无法指定这几个生命周期的。
一个构建生命周期是由多个阶段(phases)组成的上面每个生命周期是由不同的 phase 列表组成的。一个 phase 表示一个生命周期的一个 stage(这两者有什么差别?)。
default 里 phases 的顺序大致上是是 validate -> compile -> test -> package -> verify -> install -> deploy。
使用命令行如果我们使用命令:
1mvn instal ...
卡表和 RSet
上下文卡表和 RSet(Remember Set),是 JVM 为了解决分代收集时,live set 扫描需要穿梭到不同的代的时候的效率问题。
使用缓存表来提高查询效率,是化顺序查找为部分随机查找的一种常用的设计思路。
例如,在传统的计算机体系结构中,当我们把内存分成页以后,会有一个页表,页表又会有一个快表,作为一个中间缓存项,来帮助我们查找我们需要使用的页表项(table entry)。
JVM 在进行垃圾收集的时候,有一项非常重要的工作就是确定这一次垃圾收集的对象到底有多少个,即确定 live set 的范围。
对于新生代垃圾收集器而言,这个问题又有其特殊之处。根据 JVM 的弱分代收集假设(weak generational hypothesis)的存在,每次垃圾收集的时候,新生代的扫描范围可能很大,但新生代的 live set 不应该太大。card table/Remember Set 的设计目的,就是尽量减少无用的垃圾扫描范围,使用类似操作系统或者数据库的脏页表的形式,来做类似快表的查询。
卡表(card table)
卡表是 CMS 的解决方案。
卡表通常在 JVM 中实现 ...
数据建模名称规范
综合 NV + DiDi + Ali 的各种命名规范。
DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
DTO( Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
BO( Business Object):业务对象。 由Service层输出的封装业务逻辑的对象。
AO( Application Object):应用对象。 在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
VO( View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
POJO( Plain Ordinary Java Object):POJO专指只有setter/getter/toString的简单类,包括DO/DTO/BO/VO等。
Query:数据查询对象,各层接收上层的查询请求。 注意超过2个参数的查询封装,禁止使用Map类来传输。
Entity:JPA 规范下从数据持久层存储里取出来的对等对象。其实相当于 DO 。
Request:RESTful 接口的输 ...
业务分析方法
背景从 prd 出发,分析业务需求,寻找可以创造价值的方案。
业务分析的价值
全面分析用户的各项需求
告诉我们“做什么”
业务分析的目的
理解产品需求,识别业务范围
分析业务模块的重要程度、优先级
发现产品设计的不足
为后后续测试分析做准备
业务分析方法-整体过程用不同的动作达到不同的产出。
理解
需求背景(必须)
举例:阿里巴巴账户体系要初步阐述:1. 产生什么价值。 2. 需要解决什么问题。3. 甚至要阐明要达到什么目标(比如,基于支付宝账户体系统一账户id)。
现状分析(必须)
产品定位
现有业务架构
产品业务范围
规划业务架构(1. 要有分期的意识,识别产品形态。 2. 要有清洗数据的方案,预测安全风险)
识别(抽象分析建模)
业务角色(实际上就是系统交互的输入方,有多少个角色,就需要关注多少个东西)
自然人
其他系统
业务串联(为了找业务用例。业务串联就是把一堆文字描述串在一起)
业务用例(建模-业务用例图 用例是对场景的概括)
分析业务用例(建模-活动图 活动图是对用例的拆解)
提炼(进一步建模)
关键流程 由活动图的 action 逐一用流程图分析, ...
系分方法论交流笔记
分析、设计和架构的区别系分 = 业务分析 + 系统设计
系分其实就是 Analysis + Design
业务分析才是最重要的大头要理解:
架构约束
项目约束
要有:
权衡
选择的过程
理解业务,要理解业务背后的东西,产出的是模型。一步一步走,推演出来解决方案,要有方法论。
系统设计是很明确的工作了应用设计 + 数据设计 + 技术设计 = 系统方案
要考虑的额外问题:
非功能设计:运行关注点、运维关注点、开发关注点、测试关注点。
项目约束
常见方法论用例驱动设计SOAD 面向服务的分析和设计OOAD 面向对象分析和设计DDD 领域驱动设计
DDD特别适合复杂系统。有一个以不变应万变的对象,才可以在未来承载复杂的业务演进过程。这几种方法论可以混合使用。
需求分析与业务建模把 prd 从薄读到厚,把文档中缺失的部分补全。
系分做 PRD 评审的时候,影响比较大的点一定要尽早确认。一些对系统变化可控,可预测的变化,可以暂时放过,后续在补充。
面向服务的业务建模分析主业务服务,设计业务功能域,设计业务功能域边界。这个过程可能不断地螺旋式地重构。
如果用泳道来画流程图,则每一个泳道都 ...
Docker 与存储
写在前面的话容器的默认状态难以从容器中搬运出来。
容器的默认状态是基于联合文件系统的,也就是需要存储驱动的支持,效率会比直接写到宿主机文件系统里要差一点。
所以此处 storage driver,就正对应 network driver 了。
把数据写入到宿主机上的方法有:volumes 和 bind mounts。如果在 linux 上,还有 tmpfs mount。注意,这些东西不是 storage driver。
他们之间的关系是:
在操作系统和 docker 层面,可以认为 volumes 是有实际存储的设备(虽然被虚拟化)的抽象(在 k8s 抽象里是 volumeMounts),而 mount 是带有 path 的一个挂载点(在 k8s 抽象里是 mountPath)。
Volumes在宿主机文件系统上,Volumes 使用一块专属的路径来存储 docker 文件,如/var/lib/docker/volumes/,其他进程不应该碰这些文件。
Volumes 是 Docker 持久化数据最佳的选择。
常见创造数据卷的方法只能迟至容器创建时把一个数据卷和容器关联起来。
是d ...