谈论架构师的时候到底在谈论什么

  • 同理心的修炼:认同他人的能力

你接手的代码量,比前面我们架构实战案例 “画图程序” 长得多,动辄几百万甚至上千万行的源代码。文档也要少得多,没有清晰的网络协议和接口文档,更别提详细设计文档。有句程序员界的名言:“程序员最讨厌的两件事情:一件事情是写文档,一件事情是接手的代码发现没文档”。这是很真实的对现实的写照。

最值得研究的是重构。重构不为改善用户体验,它的目标是为了改善系统质量,清除代码中的臭味。但现实中也有不小比例的重构实际上是在让问题变得更糟糕。

架构师最重要的是有同理心,要有认同他人的能力。不要在没有全面理解他人思想的情况下去调整既有代码的设计逻辑。

经验积累得多了,看到源代码就能很快体会别人的思想。这背后所依赖的,其实也是架构能力。架构师往往对一个需求场景会有多条实现路径的思考和评估。这样的思考和评估做多了,看到别人的代码就容易建立熟悉感,一眼看出别人的思路是什么。

  • 全局观的修炼:保持好奇心与韧性

有了骨架,就有了全貌,有了全局的视角。

很多人都有关于 “广度” 与 “深度” 的辩证与困惑。全局观这件事情,对于心性上的修炼,比的是好奇心与韧性。

保持对这个世界的好奇心。看到新科技与新思想,先认同它,去体会它,理解它产生的需求背景与技术脉络,以此融入自己的知识体系。

怎么深耕,更多的是结合自己的工作内容和兴趣。很多工程师会有困惑,觉得自己的工作内容平淡无奇,没法让自己进步,但实际上瓶颈不在于工作内容,在于自己心性的修炼。

  • 迭代能力的修炼:学会否定自己

关于码代码,不少优秀的工程师都有这样的体会:洋洋洒洒写了好多代码,过了半年一年,自己看着怎么看怎么不爽。

你是捏着鼻子忍着,继续接老板安排下来的新任务;还是,百忙里抽出一点时间,把之前写的代码改到你满意的样子。

通过迭代而升华。这是架构能力提升之路。你的收益不会只是你重构的那一个模块本身。通过重构,你建立了新的知识体系。它是内在根本性的变化,看不见但你自己可以体会得到。

从技能来说,我们可能把架构师能力去归结为:理需求的能力;读代码的能力;抽象系统的能力。

架构师修炼之道更难的是在心性上,这包括:同理心的修炼,认同他人的能力。全局观的修炼,保持好奇心和学习的韧性。迭代能力的修炼,学会反思,学会在自我否定中不断成长。

笔者认为架构师练成非一日之功,在于日积月累,平凡的事也能做出不平凡的事。核心点在于方法的使用,理解别人的框架(同理心),持续迭代和反思。

摘录自《许式伟的架构课 - 心性:架构师的修炼之道》。

一种Vue组件引入报错解决方法

代码异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vue.runtime.esm.js:587 [Vue warn]: Unknown custom element: <search_ui> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> <FormRenderHt> at src\components\FormRender\module\form-ht.vue
<HTUi> at src\components\FormRender\widget\element\HT.vue
<ElRow>
<ElForm> at packages/form/src/form.vue
<FormRender> at src\components\FormRender\module\form.vue
<FormRender2> at src\components\FormRender\module\form2.vue
<ProductEdit> at src\views\ordercreate\product\productInfoEdit.vue
<Index> at src\views\ordercreate\main\index.vue
<App> at src\App.vue
<Root>

原因分析

  • 组件引入方法有问题,不符合vue语法。例如 importcomponents 都需要放入引入的自定义组件。
1
2
3
4
5

import FormRenderHt from '@/components/FormRender/module/form-ht'
export default {
components: { FormRenderHt },
}
  • 组件引入方法无问题,不符合vue机制。

通过对比分析,排除第一种异常情况,聚焦在第二种情况。可能的原因出现在:

  1. 异步引入产生的组件延迟引入,一个同步异步问题。(解决,修改组件引入都为异步)
  2. 组件嵌套太多,vue本身不支持这么多嵌套。(排除,支持多级嵌套)
1
2
3
4
5
// FormRenderHt 内部存在异步组件, FormRenderHt的引入也采用懒加载引入
const FormRenderHt = () => import('@/components/FormRender/module/form-ht')
export default {
components: { FormRenderHt },
}

参考

Java与JS去掉小数部分的方法

由于除法、编程语言等特性,小数计算总是可能无法获取到精确的结果。但是金额计算又要求有精确的结果,这样的矛盾可以通过整数计算加去除小数部分来获取想要的结果。

  1. 乘法: 单价为9.99元的某物品购买9个,总价为89.91元。
  2. 除法: 总价 89.90,数量为9,通过舍去小数部分的单价为 9.98。

解决办法: 将元为单位的金额乘以100换算为分进行计算,对结果取整,除以100获得真实金额。

1
let price =  Math.floor((89.90*100)/9)/100

JavaScript 处理方法

JavaScript 去掉小数部分的方法

常用的去掉小数部分的方法:

  • Math.ceil(.6) // 向上取整,向上舍入到一个整数
  • Math.floor(.6) // 向下取整,向下舍入到一个整数
  • Math.round(.6) // 四舍五入,舍入到最近整数
  • Number.toFixed(n) 四舍六入五成双,保留小数

toFixed它是一个四舍六入五成双的方法(也叫银行家算法),”四舍六入五成双”含义:对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”这里“四”是指≤4 时舍去,”六”是指≥6时进上,”五”指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是偶数)

1
2
3
4
var price = 10.99;
var quantity = 7;
var needPay = parseFloat(price * quantity);
// needPay的正确结果应该是76.93元 但是运行后发现needPay为76.93000000000001
  • 通过 Number.toFixed(2) 方法修正。
  • 将元为单位的金额乘以100换算为分进行计算。s
1
2
3
4
var price = 10.99
var quantity = 7
var needPay = Math.floor(parseFloat(price*100 * quantity))/100;
// parseFloat(price*100 * quantity)的计算结果是7693.000000000001 使用Math.floor()方法向下取整,再除100 即为正确的结果

JavaScript 保留小数两位的方法

通过 Number.toFixed(2) 方法实现任意小数的保留

1
2
3
4
5
6
// 通过 Number.toFixed(2) 方法
var price = 10.9
var quantity = 7
var needPay = Math.floor(parseFloat(price*100 * quantity))/100;
var needPay2 = needPay.toFixed(2)
// parseFloat(price*100 * quantity)的计算结果是7693.000000000001 使用Math.floor()方法向下取整,再除100 即为正确的结果

Java 处理方法

Java 去掉小数部分的方法

  • Math.ceil(0.6) //向上取整,向上舍入到一个整数
  • Math.floor(0.6) //向下取整,向下舍入到一个整数
  • Math.round(0.6) //四舍五入,舍入到最近整数
1
2
3
4
double price = 10.99;
double quantity = 7;
double needPay = Math.floor(Double.valueOf(price*100 * quantity))/100;
System.out.println(needPay);

Java 保留小数两位的方法

  • DecimalFormat
  • String.format(“%.2f”, f)
  • NumberFormat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class BigDecimalFormat {
double f = 111231.5585;
public void m1() {
BigDecimal bg = new BigDecimal(f);
double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println(f1);
}
/**
* DecimalFormat 转换最简便
*/
public void m2() {
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(f));
}
/**
* String.format打印最简便
*/
public void m3() {
System.out.println(String.format("%.2f", f));
}
public void m4() {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(f));
}
public static void main(String[] args) {
BigDecimalFormat f = new BigDecimalFormat();
f.m1();
f.m2();
f.m3();
f.m4();
}
}

参考

Spring 生态解决方案

  • Microservices 微服务
  • Reactive 响应式编程
  • Event Driven 事件驱动编程
  • Cloud 云服务
  • Web Applications 网络服务应用
  • Serverless 无服务计算
  • Batch 批量计算

Spring 开发软件框架

Microservices 微服务解决方案

Spring Boot 可以作为最小单元进行微服务架构的开发。
Spring Cloud 提供容错、易管理的微服务架构方案。

Microservice architectures are the ‘new normal’. Building small, self-contained, ready to run applications can bring great flexibility and added resilience to your code. Spring Boot’s many purpose-built features make it easy to build and run your microservices in production at scale. And don’t forget, no microservice architecture is complete without Spring Cloud ‒ easing administration and boosting your fault-tolerance.

  • What are microservices?

Microservices are a modern approach to software whereby application code is delivered in small, manageable pieces, independent of others.

  • Why build microservices?

Their small scale and relative isolation can lead to many additional benefits, such as easier maintenance, improved productivity, greater fault tolerance, better business alignment, and more.

编码设计过程效率提升和开源工具完美使用指南

在日常的 Java Web 开发过程中,笔者已经能够找到所有的免费的编码软件和办公软件替代集合,其中大部分是开源的。以 MySql 数据库客户端为例,使用 MyCli 自动提示和高亮进行快速的 Sql 编写,基于 Python 语言编写。使用 PlantUml 能绘制出目前软件设计过程的建模图形,基于 Java 和 Graphviz。老牌的 WPS 能够满足日常办公 Offie 系列的文档编写和查阅,值得称赞的是在以 Windows Mac 为主流的软件氛围下,它提供的 Debian / CentOS 也很好用。还有一个值得注意的现象是有些免费软件是强强联合的产物,例如 VS Code 、 VirutualBox 、MySQL Workbench 。

工具确实提升了办公和开发的效率,过度的依赖工具却并不是好事。国外公司、组织或基金会大多数都以开源为导向的进行软件编写。开源并不等于无限制使用,因为涉及到很多开源协议。笔者这里不细提。至少目前在完全不用盗版软件的情况下可以完成编码、设计等任务。总的来说,开源作为一个全球的协作编码过程,让开发者或组织都受益。在开源的氛围中,站在巨人的肩膀上,个人开发者也可以很容易写出一个软件。

以下为全部工具集合。

项目延期的解决办法

项目延期了,一个是会导致做了的东西没有价值,丧失了努力的动力。二个是项目挤压越来越多,导致后续跟不上项目迭代,加班加点越来越多。

导致项目延期的原因有很多:

  1. 需求变动,项目延后或者提前发布。
  2. 人员安排不合理,无法按时完成。
  3. 开发人员请假有事忙着其他的业务做。

来自军哥的解决办法分享:

  1. 提前识别依赖。前后端分离中的接口依赖,服务接口的依赖。
  2. 识别关键路径。新的迭代项目都有关键路径,比如电商环境的下单流程,提前打通关键流程就可以提高信心。
  3. 提前发布预生产环境。提前一天发布到预生产环境,倒逼产品测试。

常见经济周期说明

经济学们家早就研究出了3-60年的循环周期。

  • 每3-4年,企业的原材料库存会由空到满,由满到空,这个库存循环,叫基钦周期。
  • 每8-10年,企业的生产设备就会由新购到淘汰,由淘汰到新采,这个设备更迭,是朱格拉周期。
  • 每15-25年,房地产和建筑业就会由新建到过剩,由谷底到高峰,这个地产周期,叫库兹涅茨周期。
  • 每45-60年,顶尖科技就会由兴盛到衰落,由衰落到新生,这个技术变革,叫康德拉季耶夫周期(也叫康波周期)。

每一个周期,都有萌芽、发展、高峰、衰退,如波浪起伏。

  • 在萌芽期,创业氛围浓厚,英雄崭露头角,就像恒大当年,是广东地产四小虎,
  • 在发展期,央行刺激经济,社会现金充足,有志者快马加鞭大干快上,各路大佬大鳄脱颖而出,
  • 在高峰期,社会流动泛滥,股市一片红火,企业家不务正业泡女明星,白领们都想超越巴菲特,
  • 在衰退期,各界收紧银根,杠杆纷纷暴雷,过剩产能出清,在萧条和反思中开启下一轮循环。

认真生活认真工作

好好工作,好好读书,认真生活。

只需在日常生活中扮演好社会赋予自己的角色,或者对于自己应该做好的事情——公务、家务、学习——都要尽心尽力,孜孜不倦,锲而不舍。这个过程本身就是磨炼人格的修行。

第一种人,是不想工作但不得不工作的人。

1、 这种人,如果是员工,他们追求“钱多、舒适、宽容的工作”;如果是创业者,他们追求“赚快钱”。他们面对现实中容易失望,容易抱怨公司与外部环境,或经常跳槽,或浅尝辄止。
2、 他们总以“没找到自己喜欢的工作”为借口,在工作中不用心,不耐烦,不全心全意投入。
3、 碰到困难与挫折,容易找借口放弃努力。

第二种人,是赚钱第一、工作第二的人。

这种人对待工作与责任不很用心,只求完成不求完美,有时甚至为了赚钱而不择手段,牺牲工作与责任,损人利已。

这两类人,他们有一个共同点,就是都不尊重工作、不忠诚于工作与责任。对他们而言,工作不是生命真正的需求,是为了谋生不得不做的事情,是一旦有了条件后想要摆脱的事情。

自由软件与 Richard Stallmen

自由软件与 Richard Stallmen

“自由软件”和“开源”基本上指的是同一范围的程序。然而,出于不同的价值观,它们对这些程序的看法大相径庭。自由软件运动为用户的计算自由而战斗;这是一个为自由和公正而战的运动。相反,开源理念重视的是实用优势而不是原则利害。我们因此不赞同开源运动,也不使用开源这个词。

“要说一个软件是“自由”的,这意味着它尊重用户的基本自由:自由地运行这个软件,学习和修改它,以及重新发布它的原版或修改版。这是个关于自由权利的问题,而非价格高低。我们讨论的自由是如同自由言论般的权利,不是免费赠饮一样的大派送。”

“开源软件和自由软件这两个词在很大程度上描述的是同一类软件,但是它们所基于的价值观却有着本质上的区别。对于自由软件运动而言,自由软件是一个道德底线,是对用户自由的基本尊重。开源软件则与此不同,开源哲学考虑的是怎么做把软件做得“更好”—仅仅从实用的角度。开源的哲学里,非自由软件之所以不好,是因为他们采用了一种劣等的开发方式。”

”作为自由软件运动的成员,我们并不将开源阵营视为敌人。我们的敌人是专有(非自由)软件。但我们希望人们至少应该知道,我们所捍卫的是用户的自由。所以我们不愿被开源支持者们贴错标签。我们倡导的并不是 “开源”,我们反对的也不是 “闭源”。为了清楚起见,我们要避免使用这些词汇。”

自由软件是一种软件分发和开发模式以及自由的价值观,开源软件是一种软件分发和开发模式。