从2010年起,工作的重心与研发的联系越来越紧密。非科班出身,边学习边工作。十二年饮冰,步步皆艰辛。访问最多的网站肯定是某搜索引擎,使用频次最高的按键依然是Ctrl+C和Ctrl+V. 开始时战战兢兢,只会敲命令背语法亦步亦趋,到14年开始创业已是放荡不羁不换行不注释无所畏惧,再到隐入城市,在城中村中求静,潜心打磨产品,一不小心,就已过了4年有余,产品也由套框架、买主题,上线测试,用户评议、合规注册,再到改版重构,数次迭代,渐渐累积了各种矛盾各种负面情绪,或当然还会有敬畏。显然市场竞争技术研发产品进化是逆水行舟不进则退,无论从何角度看都没有躺平的意愿。而前进的诱惑和担忧,却又彷若夫妻有七年止痒,市场反响褒贬不一,用户反馈噪杂无序,微弱的性能优势在价格竞争中不值一提,研发资源有限却又被各种任务快速消费。产品的历史是往日的荣光,但更可能是三体人的智子,锁死了前进的道路。
而我们清楚的知道,如果不前进就一定会死 同时我发现,这个产品的第一代第二代乃至一直陪伴这个产品成长的小伙伴,在现有体系、架构,维护起来渐感力不从心的时候,往往都希望有一个“破壁者” 但下一个迭代,如果方向不对,就是一个陷阱,很容易陷入某种困境,而跳出来,方有可能在上一个阶梯。
抱怨1:测试与开发之间
1. 关于流程:提测单里不写测试范围或者寥寥几句跟没写一样!系统中提交的bug开发都不及时处理,也不看测试邮件!
2. 关于标准:为什么开发写完代码都不自测就扔给我们?测试提的bug不能复现、优先级还设置为major!
3. 关于资源:谁在测试环境调试?谁动了我们的测试数据?我们开发环境没数据,不用你们的用谁的?
4. 关于态度:测试什么都不懂…跟你说不清楚用户根本不可能这样用,你们整来整去净瞎耽误工夫你们安排计划时根本不考虑测试,三天,三天怎么可能测得完!
...诸如此类...
抱怨2:市场与后端之间
抱怨3:实施与研究之间
抱怨4:需求与设计之间
什么是囚徒困境
囚徒困境是博弈论中的一个经典理论
1950年,梅里尔.德莱希尔提出了“囚徒困境”的游戏。杜克将这一想法定型完善。
两个罪犯被当作嫌疑犯抓获,隔离囚禁候审,二人均在思考招供还是不招。
若二人均不招,各判半年徒刑;
若一人招拱,另一人不招,招供者立功释放,不招者判10年徒刑;
若二人都招,各判2年徒刑。
因无法沟通,二人困惑不已。发明者以这一游戏透示社会生活中普遍存在的一种状况。
在企业里面,通常存在如下类似的困境:
一名经理,数名员工; 前提,经理比较苛刻;
如果所有员工都听从经理吩咐,则奖金等待遇一样,不过所有人都超负荷工作;如果某人不听从吩咐,其他人听从吩咐,则此人下岗,其他人继续工作;如果所有人都不听从经理吩咐,则经理下岗;
但是,由于员工之间信息是不透明的,而且,都担心别人听话自己不听话而下岗,所以,大家只能继续繁重的工作。
上帝视角不应只存在于老板眼中
电影《教父》里有一句台词:「花一秒钟就看透事物本质的人,和花一辈子都看不清事物本质的人,注定是截然不同的命运。」
而系统思维,可以简单的以老板看问题看事情的角度来类比。
从工作本身而论:
程序员通常执着于某段代码某个功能的实现。 老板看到的是这个功能能不能迎合市场取悦顾客,能不能卖出产品,以及实现这个功能所需的成本、时间、资源。
而这最终要求产品经理、研发、测试,在产品研发的全生命周期,具备一定的视野,不一定是全局的、系统性的,但至少要分得清,这个系统是什么,由什么组成、组成的流程和链接关系、链接路径,最终实现了什么功能,满足了市场的某个需求
从企业文化与工作氛围来说:
我们当然没有办法要求每个人都一定都视野或格局,或经验沉淀,来聚焦核心,或是高屋建瓴,也不可能要求把什么事情都想的面面俱到。 但“宰相起于州部 猛将发于卒伍”,今天不敢想,不深入的想,忙忙碌碌看上去活就没停过,最后发现,要么交付的东西与最初的用户需求或问题,已南辕北辙,捡了芝麻丢了西瓜,要么是是改进了A功能,引入了B隐患或缺陷,最终顾此失彼。而这样的人生,看上去这么辛苦,产物确实一塌糊涂,与测试扯“设计如此”、与老板讲“资源局限性和妥协”、与客户强调“客观条件”,最终陷入“相互指责”、“借口与推脱”、“相互摆烂”的囚徒困境。
而囚徒困境下,员工与老板、与企业是双输并且将一直输,除非事情得到改善。 很简单的逻辑:工作辛苦、产品不出众、企业市场竞争处于劣势、效益差、薪水低、工作幸福感更差,于是下一个版本下一个产品更…..死循环直到企业消亡。 而在这个时间段,企业与老板,输的是可量化的经济损失。但对工程师而言输了什么?输了职场的黄金时间,输了职业生命周期。而这,是决定一个工程师能否成长到高级/资深工程师或架构师,走上职场金字塔巅峰的起点。输在了起点,基本上,即可宣告
在
系统的定义
德内拉•梅多斯在她的著作《系统思考》中的定义:
系统是一组相互关联的元素,它以一种可以实现某些东西的方式联系起来。
所以,我们可以将系统分为: 环境:系统的运行环境、硬件、操作系统、使用场景; 要素:在系统里,最核心的要素是什么? 互联:要素之间是如何连接的?它们之间的关系是怎样的?它们进行输入和输出的途径是什么? 目的:产品最终想要达到的目的是什么?程序和功能并不是目的,帮助使用程序或功能的人解决某种问题达成某个目标,才是系统设计、产品研发的根部目的。
套入我们辅助诊断系统:
环境
操作系统:Centos7 64bit/一切64位的linux操作系统(特别是基于Linux衍生的国产操作系统,在以后越来越重要),或Windows操作系统 使用场景:病理科边扫描边计算,当切片量大、扫描设备多时,扫描、计算、阅片复核,同时进行是常态。 硬件环境:
组件 | 供应商或品牌或架构 |
---|---|
CPU | Intel/AMD/ARM(华为)/Apple M |
内存 | DDR家用级/服务器级(ecc) |
存储 | local(ssd/nvme ssd/sata) remote(nas:nfs/cifs/fc/vfs client/fuse client) |
网络 | 介质:ethernet/fiber 连接:lan/wan |
计算卡 | GPU:nvidia(cuda)/amd(romc)/华为/Google/xilinx(fbga) |
软件环境:
读取:
- 传统读取 open:Unix底层调用函数,返回的结果是文件描述符,即文件句柄,一般面向设备时使用open fopen:C 标准函数,返回的是文件指针,需要正式打开文件、判断文件打开状态,容错,一般使用fopen,建议面向文件时候使用。 popen:fork子进程打开,将返回的指针供父进程调用
python 里面的open,使用的fopen还是open还是popen ? 通过阅读源码,我们发现python 使用fopen;
read
fread
seek
fseek
close
fclose
write
fwrite
-
编解码 libjpeg jxrlib openjpeg jp2
-
压缩 zip lzw
-
同步/异步io
-
特定的网络IO
-
机器学习中的数据加载
1.4 缓存
处理:
| 上层Api | 底层库与依赖 | 用途
| —– | ——— |
Pillow | Tcl/Tk |Pillow 是 PIL 的替代版本,PIL 软件包提供了基本的图像处理功能,如:改变图像大小,旋转图像,图像格式转换,色场空间转换,图像增强,直方图处理,插值和滤波等
opencv-python| opencv | 用途与Pillow类似,调用opencv,根据功能和需求的不同,OpenCV中的函数接口大体可以分为如下部分:core:核心模块,主要包含了OpenCV中最基本的结构(矩阵,点线和形状等),以及相关的基础运算/操作。imgproc:图像处理模块,包含和图像相关的基础功能(滤波,梯度,改变大小等),以及一些衍生的高级功能(图像分割,直方图,形态分析和边缘/直线提取等)。highgui:提供了用户界面和文件读取的基本函数,比如图像显示窗口的生成和控制,图像/视频文件的IO等。如果不考虑视频应用,以上三个就是最核心和常用的模块了。针对视频和一些特别的视觉应用,OpenCV也提供了强劲的支持:video:用于视频分析的常用功能,比如光流法(Optical Flow)和目标跟踪等。calib3d:三维重建,立体视觉和相机标定等的相关功能。features2d:二维特征相关的功能,主要是一些不受专利保护的,商业友好的特征点检测和匹配等功能,比如ORB特征。object:目标检测模块,包含级联分类和Latent SVMml:机器学习算法模块,包含一些视觉中最常用的传统机器学习算法。flann:最近邻算法库,Fast Library for Approximate Nearest Neighbors,用于在多维空间进行聚类和检索,经常和关键点匹配搭配使用。gpu:包含了一些gpu加速的接口,底层的加速是CUDA实现。photo:计算摄像学(Computational Photography)相关的接口,当然这只是个名字,其实只有图像修复和降噪而已。stitching:图像拼接模块,有了它可以自己生成全景照片。nonfree:受到专利保护的一些算法,其实就是SIFT和SURF。contrib:一些实验性质的算法,考虑在未来版本中加入的。legacy:字面是遗产,意思就是废弃的一些接口,保留是考虑到向下兼容。ocl:利用OpenCL并行加速的一些接口。superres:超分辨率模块,其实就是BTV-L1(Biliteral Total Variation – L1)
计算:
存储: 队列:
组成要素
- 数据要素: 在病理科,主要的数据是切片,而切片与患者、病例、报告的对应关系如下: 患者——病例(一个患者在一个机构,一般只有一个病例号)——检查号(一个患者,可能有多次检查,每次检查的病理号不同)——切片号(细胞病理单切片,病理号等于切片号,组织病理多切片)
- **
数据与交互
核心功能
套入我们辅助诊断系统,要素和互联分别是什么?
要素 :
研发时的系统思维
设计阶段
- 功能性设计
- 接口与集成设计
- 可靠性设计
- 性能设计
- 交互设计
- 安全设计
编码阶段
测试阶段
人工智能的测试难在哪? 拙见有如下几点:
- 算法性能
- 系统性能
- 可靠性
- 安全性
难的事情才有价值
我以前读书的时候有一个习惯,数学题总是喜欢先解决后面的难题
这个习惯不一定好,也不一定能拿高分。但是在企业做产品搞研发的时候,却往往会发现、遗留一些难题或痛点,这些难题或痛点,可能是行业通病,也可能是自身的缺陷。但在宏观上,行业有痛点,产品才有卖点,缺陷存在,产品即有提升空间。而技术难题的解决,对于自身成长、产品圆满、公司发展。 但是我们要避免设计或研发使用起来特别复杂,技术难度非常大的要素。很多工程师或产品经理会设计一些使用起来或开发过程很复杂,技术难度很高的功能,他们有一些可能是必须的,有一些可能是可有可无的,即使它们是必须的,在用户交互设计和界面上,也要化繁为简, 发现新的可能性:通过打乱系统中固有的状态,我们可以有更多的时间来考虑自己能够为用户提供支持的创造性方法。在这个系统后面,我们有一个机会来创造一个建议系统,它在帮助用户最终有效地解决自己的问题时扮演了重要的角色。 行动起来:在你事先对完整的系统有了清晰的了解之后,你就更容易从工作凝聚出最重要且最有影响力的部分,并避免随着项目的推进出现方向上的偏移。所以说,一旦系统的核心部分建立起来,后续的添加和修补工作就容易很多。 利用现有的设计:一致的UI(用户界面)模式和组件会为你省下不少的工作时间,从而加快项目的进程。所以,并不是所有的东西都需要从头开始创建,一个例子就是我们的内容反馈机制。当用户阅读疑问解答时,我们希望为其提供一种反馈内容有效性的方式。而在我们原有的系统中,已经存在一个具有相似逻辑的产品。从概念设计到落地实验,从悬浮效果、转换细节到单击分享,我们都重复利用之前的设计组件。
不提倡甩锅文化
- 现场观测所得,为现象,不针对特定的某个人或某个功能模块
- 现象不等于故障,不好的现象说明我们有提升的空间和不足的地方,有提升才有未来
- 现象或分析现象产生的原因,责任落实到某个功能的某个人、某个环节的某个人,不是为了对这个人进行指责或处罚,针对个体的处罚不值一提。
- 竞争环境恶劣,产品品质优秀质量可靠性能高效,才能让用户满意且买单,公司才有发展前景