2019-04-14

谈谈软件工程

考虑人的工作产出为x,时间为t,对应需要支付的成本为s.
那么一个profit=x*t-s

如果令s的支出跟t简单相关则有
profit=(x-c)*t.

简单地,所谓的剩余价值约束工作时长.

这里有两个隐含假设.
一个是x是恒定的,也就是单位时间贡献不浮动.
而是s跟t线性相关.

也就是这里收益和成本都是简单线性描述.

考虑x为一个带一定衰减的函数.
比如X(t) = W*(1-e^-t).
一个bounded by W且随时间增长效率递减的函数.

那么profit=\int_{0}^{t} W*(1-e^{-t})dt - c*t
->
profit=t+e^-t+R-c*t
->
profit=e^(-t) + (c+1)*t + R

如果以天为周期小时为单位计量的话.
大致回报也是线性的.

一般地来说,在给定的时间范围内,只要X的derivative为正的话.
也即是时间计量的margin为正.
那么incentive就自然会是增加时长.

那么如何构造在一定时长后margin为负的情况呢?

最简单的负值构造自然是线性的.
对应的就是抛物线.
即X(t)=a*t^2+b
->
profit=a*t^2+b - s*t
->
profit=W(c-t)^2 + d

在这种情况下才可能存在给定某个工作时长为最优解形式.
如果是存在最大值的话,那么应该有W>0

也就是这个X应该是一个会在某个时间点之后incur performance degrade的曲线.
这不算是一个不现实的约束.

其他的形式呢?

考虑相对一般的形态.
profit=return(t) - cost(t)
或者
profit=\int return(t) - \int cost(t)
对应的return和cost曲线的对t的integral差异.
即投入和成本曲线的差额.

对于单个个体来说,如果需要maximize profit/on return的话.
相对stable的IC曲线应该是会让问题相对简单的.

这就需要每个人的投入产出以及对应的成本是相对可计量/具有统计意义的.

大多数情况下个人的cost是相对可预测/固定的.
所以这个求解的关键在于个人的time investment return的模式问题.

只要产出模型是有正margin的,那么单纯延长时间是没问题的.

比较麻烦的是那些曲线比较复杂,或者根本不连续甚至在一定周期尺度下具有随即性质的.
这种可能是根本没有明确的解析解的.

从群体尺度来说的话.

在数量到达一定程度的时候,个体的模式浮动性特征是比较容易被表征出来的.
也就是说,到达一定规模之后,理论上来说是可以规约到某一种特定的产出模式上作为当个个体求解的.

但是也并不是就一定存在解.

因为形式上来说,解的存在性和形态取决于产出模式.

那么软件工程是或者说应该是什么样的产出模式呢?

可能软件工程这个提法本身就是比较微妙的.

记得上学的时候就有各种CMMI/敏捷/测试/设计模式等方面的各种宏观架构.
各种方法论解构下来不过就是拆解.

背后的逻辑不过就是把不可控控制在一个认为可控/bounded的范围内.

它可能笑起来像金融的risk control/estimate.
但是至少金融有一套稍微能跑起来自洽解释的计量和数值系统.

而软件工程理论是不具有这些特征的.
最后无论以什么方式拆解出来的方案/步骤/方案,最后指向的是一个单一的计量标准.
也就是时间.

是的,金融方面也不过最后会量化为交易价值.

但两者的不同在于,时间的定量本身是未定义.
或者说没有标准的.

就像敏捷提出来优与瀑布或者更传统的软件开发模式的时候.
一个论点就是拆解的时间单元比对方更小,从而更flexible,更能应对各种可能发生的情况.

至少在这个陈述里面,它没有回避说软件开发的难点在于 各种可能发生的情况 这种风险.
但是逻辑上却微妙地归结到更小而短的周期能够让这种风险的发生几率更低.

那么如果这个观点如果是对的话,imply的就是软件开发的风险在与周期长.

这样就实际上陷入了一种递归指责.
或者说是一个逻辑陷阱.

在没有办法定量指出风险的具体含义的时候,提出了解决风险的方式.

所以,能实施成功的话,也只是因为刚好恰当地风险主要因素确实是时间.

那么,软件工程的风险到底是指什么呢?

可能在于软件工程这个提法本身.

coding本身有所谓的工程化的么?

或者说工程化本身的含义是什么.

一般的工程化可能跟接近于科学的定义.
即是一种能够量化衡量的可重复实验/过程.

coding本身是不太具有量化标准的.
就像文章或者绘画.

即使以统计的角度来说,量化能覆盖的也不过是风格上的问题.

但是完全没有能够bound的东西也不尽然.
至少API/protocol算是一种.

但是这是在integrate阶段的.
这个时候才会有简单的satisfied or not.

所以如果软件工程如果说存在的话.
也应该指示的是在delivering service过程中的这些隼合情况.

实际上,这些理论上是包含在automation里的.
包括compile/build/test/deploy基本都是不需要也不应该由人去干涉的.
而是根据各个节点的specifications来judge的.

再回头看那些工具和方法论.

那么当所谓risk出现的时候,大致就是各个pipeline stage的合规情况出现问题.
这时候这些理论是怎么解决这些问题的呢?

并没有.

或者说也有.

因为在这些理论框架下需要满足的constrain是时间.
如果把它作为所有risk的一个proxy来看待的话.
由于这些工具所处理和解决的都是在满足time bounded的前提.
于是在proxy回实际的处理方案的时候,关注点也通常在如何回避对时间的default.

于是实际执行上,如果build或者test或者deploy或者任意阶段出现问题.
那么可能的做法就是直接抛弃约定,做default处理.

所以这里的核心矛盾就在于.
或者说一个简单的模型描述就是.

给定一定的time resources.
以及一组random generated的consumer.
如何用limited的resource去satisfy的问题.

而这个是无所谓解的.

除非是能够bound consumer.
要么有一定的确定可预测的范围,要么具有某种可描述的模式.

所以,归根到底还是know your issue.









2019-04-06

由铁路售票想起

候车的时候想了个问题.

其实列车售票是一个segment的allocation问题.

给定一条线路{s_0,s_1,...,s_n}.
一个从A->B的请求实际上是某个{[s_i,s_j]; 0<=i 且每一个s_i有对应的一个quota,q_i表示可allocate的数量.

那么一个naive的approach就是做一个atomic的能rollback的transaction,做一个decrease.
这样的话,在q_i <<< concurrent_request,远小于并发请求数的时候.
在给定collision分布的情况下,某些q_i就不停地<0导致transaction rollback,从而造成一个failed allocation.

考虑一个稍微简单的定义.
给定一个sequence或者whatever,{s_i;s_i=0 or s_i=1}
也就是这个离散连续区间的值为0或者1.
或者说,这条线路各站余票只有0或者1两种情况.

对于一个allocation request,a_i_j,则要求的是.
sum_i_j s_i = j-i+1,即使i,j区间均为1.

而一组concurrent request则可以认为给定一组a,求一个satisfied的allocation subset.

这个有点类似有冲突的广告bid.
或者所谓的背包算法还是什么?

考虑optimized的目标是让是个subset尽可能地大.
或者说有尽可能多的request被满足.

那么这个最优解怎么求呢.

从最大或者最小的span开始allocate是不行的.
因为很容易构造一个反例,使人如果这个最优解存在,这种策略是不work的.

考虑对non-overlay的span一次allocation.
这是一个not necessary optimal的solution.
因为没有conflict.

考虑这个allocation set中的某个请求r,存在另一个range conflict的请求r_c.

当r_c的span是r的一个子集的时候,用r_c替换r是可以improve的.
因为此时r_c release原来r range的某些slot.
这使得这些slot有可能被更多的请求allocate到,从而增大了allocation set.

如果反过来的r_c是r的一个super set的话,那么同理,是不能improve的.

考虑只是partial overlay的情况.

令L_r为r的长度,L_r_c为r_c的长度.

那么在把r剔除之后的空出来的长度L至少会是L_r + L_r_c - 1.
不然的话,r和r_c能够同时fill整个range,不会有overlay.

于是对于r的improve就递归为这个L区间的optimal solution了.

则当最终converge的时候,也就是对于当前solution的所有r,都找不到任何improve的时候.

这个是最优解么?
还是说只是一个local minimal?

应该说只是一个local minimal.
因为本质上这是个step one的back search.
存在且容易构造如果回退两步能fill 3个request的情况.

而回退两步能产生更优解的原因应该是在于有了更多的continual的space.

所以可能first fill的时候,应该以保持尽可地避免fragment?

于是理想的做法应该是优先给予线路两侧的短途?







聊聊卡布里尼

最近看了部片叫卡布里尼,算是可能这段时间来比较有意思的一部电影. 故事也不算复杂,就是一个意大利修女去美国传教,建立慈善性质医院的故事. 某种程度上来说,也很一般的西方普世价值主旋律. 但是如果换一套叙事手法,比如共产国际的社会主义革命建立无产阶级广厦千万间的角度来看的话,也不是...