lecher

lecher

V2EX 第 27664 号会员,加入于 2012-10-05 21:04:36 +08:00
今日活跃度排名 22549
12 G 70 S 76 B
pypy 拿到赞助之后出了支持 Python3.5 的版本
Tornado  •  lecher  •  2017-03-22 00:10:00 AM  •  最后回复来自 kingmo888
16
分享一个个人觉得不错的 linux 资源库 http://yp.oss.org.cn/
  •  1   
    分享发现  •  lecher  •  2015-04-08 22:29:51 PM  •  最后回复来自 ningyuqiao456
    1
    Python 3.5.0 Alpha1 发布
    Python  •  lecher  •  2015-02-26 11:25:51 AM  •  最后回复来自 yingluck
    11
    关于图片服务器的反爬虫处理请教
    服务器  •  lecher  •  2015-02-05 05:41:39 AM  •  最后回复来自 yegle
    30
    wooyun.org上今天提交了一百多个关于struts的漏洞
    信息安全  •  lecher  •  2013-07-17 20:59:54 PM  •  最后回复来自 zhttty
    14
    lecher 最近回复了
    9 天前
    回复了 shade 创建的主题 程序员 工作流 与业务数据流怎么解耦?
    就是一份数据,数据实体同时记录工作流状态,业务处理的流程同时修改实体对应的数据并提交到数据库。

    最直白的工作流描述方式类似这样
    状态 1: 响应事件 a,b,c
    状态 2: 响应事件 d,e,f
    状态 3: 结束
    处理的过程无非是,收到对 entity1 发送的事件 x,从数据库中将 entity1 查询出来,进行状态事件表查询,跳转到要执行的业务处理代码,然后服务执行这份代码对 entity1 的数据做处理,处理完后跳转到状态 y 并提交当前 entity1 经过处理后的数据到数据库,等待下一个事件。

    接着拆解一下事件的类型:
    1.外部服务发送过来的请求
    2.其它工作流发送过来的事件
    3.延时 /定时触发的事件

    可以看出来,需要有不同的协议来适配对应的事件转换:
    1.提供服务端对外接口接收外部请求,并转换成事件
    2.不做转换
    3.提供延时队列服务收发延时任务,并在指定时间发起对应的事件

    再看一下收到事件该怎么处理:
    1. 根据事件参数中的 entityName, entityID 查出数据
    2. 将数据 loaded 到 class 中
    3. 调用事件对应的 method,执行对应的业务代码
    4. method 之后需要更新下一阶段的状态标识到 class 的字段上
    5. 将当前 entity 的所有业务数据连同状态标识一并提交到数据库保存

    可以推测一下实现方式:
    1.从数据库 load 数据出来
    2.使用这份数据去 new 一个 class
    3.带着事件参数去 call class.method(params)
    4.序列化 class 的数据,提交到数据库

    这需要运行的语言支持什么特性?
    1. 可以根据字符串类名实例化一个 class
    2. 可以根据字符串方法名调用一个 class.method
    3. 方便的序列化、反序列化数据,最好是无缝与 json 形式的数据转换
    4. 能用简洁的语法描述业务处理

    不管原始业务是用什么语言写的,这些业务处理代码都可以在同一套服务进程内运行,因为本质上这就是一个请求-处理-保存数据-返回结果的流程。业务代码与正常的网络请求处理毫无差别。

    接着抛开实现细节,以请假审批为例子看看如何使用代码描述一个工作流的处理是易于阅读的。
    方式 1
    class 请假 {
    public 待发起(event, params){
    if (event === 发起){添加延时任务通知超时,发出审批通知;next(待审批)}
    if (event === 放弃){next(关闭)
    }
    public 待审批(event, params){
    if (event === 同意){更新年假业务数据;next(通过)}
    if (event === 超时了){发送超时通知;next(超时)
    }
    public 超时(event, params){
    if (event === 重新发起){修改业务数据;next(待审批)}
    if (event === 放弃){更新相关数据;next(关闭)
    }
    public 通过(event, params){
    // 空处理,仅作状态记录,不会再响应其它事件
    }
    public 关闭(event, params){
    // 空处理,仅作状态记录,不会再响应其它事件
    }
    }

    方式 2
    class 请假 {
    public process(){
    待发起:
    event = this.event
    if (event === 发起) { 更新业务数据;goto 待审批}
    if (event === 放弃) {goto 关闭}
    待审批:
    event = this.event
    if (event === 同意) { 更新业务数据;goto 通过}
    if (event === 超时了) {goto 超时}
    超时:
    ...
    通过:
    ...
    关闭:
    ...
    }
    }
    @feather12315 特别新的新手挑几个写好细节设计的文档让他写实现,尽可能调新增业务或者特别简单的 bugfix
    带着业务理解 review,我司要求 code review 的目的是为了避免单点,在代码实现的思路上让团队达成一致,至少相关业务开发人员达成一致,review 之后意味着这个模块出了问题,我也可以负责修。这样出了任何问题,review 过的人都可以直接修改代码,而不是推脱这个模块不是我写的,我不需要为此负责。
    所以在我司,code review 没有把重点放在语法之类的实现细节上,重点是在代码有没有体现合理的设计思路,代码可读性上。
    而且 code review 已经是最后一步了,功夫应该在 code review 之外。

    概要设计文档,细节设计文档,都需要有配套的评审,将技术债务尽可能减少。设计文档的评审通常是老带新,老手写概要设计框住业务边界,新手写详细设计明确实现细节,由评审来保证相关人员对业务需求的拆解理解达到一致。

    此外就是配套的 CI lint test 等支持,规范代码风格,保证功能满足需求。

    实际 review 的时候,会快速看看 test 的覆盖率快速确认对外暴露的调用约定是否合理,边界样例是否覆盖业务需求的要求。其次是看代码结构,可读性如何,再次才是语法细节,有没有不合理的写法,对于不合理的写法通常只有新人的前几个 PR 高标准评审,甚至可能有一个新人三四个老人评审的情况。

    这么带几轮下来,大部分团队成员的代码风格和业务拆解都接近一致,基本上出问题都可以让一个人一杆子捅到底层实现去定位和修复。如果发现是代码分层和架构满足不了新增需求可能还有重构的情况。

    享受到的收益是:
    test 是以业务边界为要求写的,不用担心重构的影响范围过大。
    底层模块业务稳定,容易交接,新人上手阅读代码和改代码的成本低。

    这么做的问题是,功能迭代速度太慢,一个业务需求从设计到实现拖的周期会很长。还会有不少时间放在重构偿还技术债上。
    这种模式只适合核心业务,对于开发周期急迫的任务并不太适合。
    永远保持用自动化工具解决问题的思维方式,不管是用软件还是自己写代码造工具,不要让自己在重复的事情上浪费太多时间

    保证新特性的 迁移成本+使用成本 < 旧特性的使用成本 是推进改进的最佳方式,而自动化工具是最小化迁移成本的唯一途径
    工作习惯好的程序员善于使用脚本自动化自己的重复性工作

    验证性业务的脚本,本地提交代码的预处理,业务代码的测试用例,登录堡垒机的脚本,更新工作任务状态的脚本,随手启动一个 mock 接口的 http server,都是很适合用脚本解决的问题
    77 天前
    回复了 xiaofan2 创建的主题 问与答 如何才算一篇好的技术文章
    draveness.me/whys-the-design/
    安利一个篇篇经典的 blog
    81 天前
    回复了 MeloForsaken 创建的主题 程序员 问一个系统设计的问题
    问题是如何满足频繁变更的报表需求。
    成本最低的方案其实是用专门的报表基础设施解决这几个问题:
    1. 报表计算逻辑的声明
    2. 报表同步数据

    自己另起服务定制写统计是成本最高的方案,不管你是 rpc 还是定制写计算逻辑。
    两个业务其实可以通过数据库解耦。
    不管你有多少业务项目:A1 、A2 、A3……
    业务项目只负责自己的业务数据读写的约束。

    报表业务应该只关注数据库的数据是什么样,如何通过数据库的数据计算出需要的报表,clickhouse 、tableau 、superset 这类开箱即用的报表解决方案不是更合适吗。
    做为一个去过较多省份的吃货,我发现的规律是。
    城市化+高房租+生活压力大 = 美食荒漠

    北京存在这几个缺点
    超大城市化意味着大部分食材是标准化的,平民能吃到的也只是标准化的冷鲜食材
    高昂的房租意味着不存在低廉的人工,食材加工偏向流水线作业
    生活压力过大意味着生活节奏快,大部分人没有时间用钱给好的菜品投票,饭店也没有动力改进,大幅拉低平均菜品质量
    卫生文明城市整治,绝杀小摊小贩
    北京唯一的特例是有历史积淀,但传统小吃难吃。即便算上驻京办,整体水平也不如其它省会

    好吃的城市至少以下特征的一个
    历史积淀,存在老城区或城中村,间接保留很多老店,尤其是自有房产的老店,本地菜品的顶梁柱
    生活节奏慢,大部分人有时间给好的饭店投票,愿意为好吃的饭店付出等待时间
    城区不算大,本地食材到饭桌的周期短,能提供大量新鲜食材,本地人也愿意为好食材付出成本
    早餐或夜生活丰富,尤其有夜宵

    以上北京除了历史积淀,一个都没沾上,另一个类似的美食荒漠省会是石家庄,同样难吃的饭店居多。

    就我吃过的城市而言
    第一档是广州及周边佛山顺德等
    第二档是西安、南京、乐山、昆明、瑞丽、扬州、泉州
    其它的有哈尔滨、成都、武汉、福州、重庆、天津、腾冲、保定、惠州、保山

    其它城市不是说没有好吃的,就是太少找的费劲。
    如何发掘兴趣方向,培养出有自学能力的孩子才是最费心力的。

    有太多人填鸭式的教育把孩子的兴趣爱好都遮盖了,即使现在资讯那么发达了,依然有很多人高考之后还不知道自己对什么感兴趣,也不知道什么值得自己投入精力去奋斗,服从调剂去了一个自己未必感兴趣的专业,毕业之后随大流找一份对口的工作,或者为了生活选择一个热门的领域工作。
    孩子感兴趣,从学习中获得正反馈,家庭有条件提供相应的助力,才是合理的教育模式。

    我更认可自驱力更强的竞赛式教育方式,能够在中学阶段就找到自己真正感兴趣的领域,并投入自己的精力超前学习相关领域的知识,从中锻炼培养出属于自己的一套研究、学习的方法,这才是受益终身的能力。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2597 人在线   最高记录 5268   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:01 · PVG 00:01 · LAX 08:01 · JFK 11:01
    ♥ Do have faith in what you're doing.