拿到它的时候,它已印刷了13年之久;能在京东上找到,也是极大的幸运。

《代码大全》是一部又大又全的工具书,它涵盖了关于编程各个环节的充分经验,可以作为日程编程工作的指导。将其他教我如何编程的书中的内容做了一个打包。数月研读下来,难免有所遗忘。这里将其中的精华尽量记录下来,也作为对全书内容的一个回顾。

打好基础

第1部分主要围绕构建为读者讲解什么是构建,和关于构建我们需要了解和准备的。也为后面展开具体编程细节和设计艺术打基础。

走进软件构建

构建是软件开发的核心,构建的质量对软件质量有实质影响。

隐喻理解软件开发

用隐喻可以帮助理解软件开发的过程。

  • 一个好的隐喻应该是简单的,忽略了不必要的细节,对概念进行内化和抽象,让人从更高层面思考问题,从而避免低层次错误
  • 隐喻更像启示,而非算法
  • 对于编程来说,还是将问题概念化
  • 有一些常见的软件隐喻
    • 写作/耕作:这些隐喻不太合适
    • 养殖:增量、迭代、自适应、演进的成长概念
    • 建造:规划设计文档,使用现成组件
  • 组合各种隐喻,不要过度引申隐喻,带来误导

提前准备

提前准备,降低风险。

  • 前期准备的必要性
    • 降低风险
    • 通过逻辑、类比、数据说服项目经理
      • 开始大项目前需要制定计划
      • 程序员是食物链的最后一环,架构师吃掉需求,设计师吃掉架构,程序员消化设计
      • 发现错误的时间要尽可能接近引入错误的时间,可以尽量降低修复时间
  • 判别你所在的软件领域
    • 在软件开发中,适用迭代式开发法比适用序列式开发法的情况多得多
  • 先清楚定义问题
  • 再正确认清需求
    • 正式详尽地描述需求,是项目成功的关键
      • 面向目标、契约式编程
    • 稳定需求是可望而不可即的
      • 开发过程会帮助客户更好地理解自己的需求,这也是需求变更的主要来源
    • 应对需求变更
      • 核对当前需求的质量(需要有一个需求质量的核对表),及时回退到需求设计环节
      • 确保每个人都知道变更的代价
      • 建立变更的控制流程
      • 要放弃么?
      • 考虑项目的商业价值
  • 考虑架构设计
    • 架构指整个系统的设计约束,不会细节到子系统或类的设计约束
    • 架构的组成部分
      • 程序组织
      • 主要的类和类的继承体系
      • 数据结构设计
      • 业务规则描述
      • UI设计
      • 资源管理:数据库连接、线程、句柄
      • 安全
      • 性能
      • 可扩展性
      • 国际化
      • 错误处理:纠正还是检测、主动还是被动
      • 输入输出
      • 容错性
      • 过度工程:明确设立期望目标
      • “买”还是“造”:如果架构选择自己做,那么一定要证明自己定制的组件在某方面胜过现有的
      • 变更策略:如何应对变更
    • 架构的总体质量
      • 和所解决的问题和谐一致,看起来自然
      • 描述所有主要的决策动机
      • 优秀的架构很大程度和机器与编程语言无关
  • 投入的时间一般在20%-30%

关键的构建决策

选择语言、技术、构建实践。

  • 高级语言表达力更强
    • 你思考的能力取决于你是否知道可以表达该思想的词汇
  • 提前讲好使用的编程约定,去统一编程语言的细节
  • 找准在技术浪潮中的位置
    • 如果在浪潮后期,就可以持续使用稳定的功能;在浪潮前期,则需要花时间找到文档中没有说明的编程语言特性
    • “深入一种语言去编程”,程序员现决定想表达的思想是什么,再决定如何使用特定语言的工具去表达这些思想
  • 选择构建实践

创建高质量代码

这一部分主要讲解类和子程序的设计和编码。

如何做设计

一些启发式准则和idea

  • 设计的挑战
    • 有的问题需要“解决”一边,才能明确定义它,然后再次解决
    • 设计成功应该是组织良好且清爽的,不过设计过程却并非如此
    • 设计需要取舍,受到限制
    • 设计需要启发式思维,但也是不断评估、讨论、调试实验中诞生的
  • 设计的关键概念
    • 管理复杂度
      • 软件开发的本质复杂性来自复杂无序的现实世界,精确完整地识别依赖关系和意外情况,设计完全正确而不是部分正确的方案
      • 软件需要管理复杂度,在组织程序的时候便于在一个时刻专注于一个特定的部分,另外不遗漏暂时忽视的部分
      • 应对复杂度:减少本质复杂度到最小、避免偶然复杂度的无谓增长
    • 理想的设计特征
      • 最小复杂度
      • 易于维护
      • 松耦合
      • 可扩展、可重用
      • 高扇入(类被其他类大量使用)、低扇出(类少量使用其他类)
      • 可移植性
      • 精简性
      • 标准化
    • 设计的层次
      • 软件系统 > 子系统或包 > 类 > 子程序 > 子程序内
      • 常用子系统:业务规则、用户界面、数据库访问、OS抽象层
  • 设计构造块:启发式方法
    • 寻找现实对象:想想系统要模仿什么
      • 辨识对象和其属性
      • 确定可以对对象做的操作
      • 确定对象能对其他对象进行的操作
      • 确定对象的可见范围
      • 定义对象接口
    • 形成一致的抽象:让你关注某概念的时候忽略不必要的细节
    • 封装实现细节:封装帮你掩盖不需要你看到的复杂度
    • 继承能简化设计就继承
    • 隐藏秘密信息
      • 保证接口最小且完备
      • 隐藏复杂度和变化源
    • 找出容易改变的区域
      • 业务规则、硬件依赖、输入输出、非标准的预演特性、状态变量、糟糕或复杂的设计
      • 将容易变化的部分隔离开,让变化的影响范围和变化的可能性成反比
    • 保持松散耦合
      • 耦合种类:简单数据参数、简单对象、对象参数、语义耦合(过多假设)
    • 了解常用的设计模式
      • 设计模式提供了现成的抽象来减少复杂度
      • 设计模式将抽象SOP化
      • 设计模式可以起到启发性作用
      • 设计模式将设计对话提高到更高层次来简化交流
    • 其他启发式方法
      • 高内聚
      • 契约式设计
      • TDD
      • 创建中央控制点,集中管控
      • 拿不准时,使用蛮力突破
      • 画一个图
      • 设计模块化
    • 使用启发式方法的原则
      • 先理解问题
      • 找出现有数据和未知量之间的联系
      • 寻找之前的类似问题,或者解决一些相关问题
      • 执行计划
      • 回顾解
  • 设计实践
    • 迭代:第二个尝试往往会好于第一个
    • 分而治之,增量式改进
    • 自上而下设计和自下而上设计
    • 建立试验性原型:原型要足够简单可抛弃,又足以验证效果
    • 记录你的设计成果:wiki、邮件、UML图

设计类

  • 类是一组数据和子程序的聚合,有内聚的明确定义的职责
  • 抽象数据类型(ADT)
    • ADT可以让你像现实世界一样操作实体,而不必在底层实现上摆弄实体
    • ADT的好处
      • 隐藏实现细节
      • 改动不需要影响整个程序
      • 接口语义更强
      • 更容易提高性能
    • 在非面向对象环境,也可以使用ADT
  • 良好的类接口
    • 好的抽象
      • 类接口应该有一致的抽象层次
      • 要理解类的抽象是什么
      • 考虑提供成对的服务,如打开/关闭、添加/删除
      • 尽可能让接口可编程,而不仅是表达语义
      • 谨防在修改时破坏接口抽象
      • 同时考虑抽象性和内聚性
    • 好的封装
      • 封装比抽象更强,它直接阻止你看到细节
      • 尽可能限制类和成员的可访问性
      • 不要公开暴露成员数据
      • 不要将实现细节暴露在接口上
      • 不要对类的使用者做任何假设
      • 让阅读代码比编写更方便,代码的阅读次数比编写多得多
      • 不要透过接口来编程,仅仅看类的接口文档无法得知如何使用一个类的话,正确的做法不是拉出类的源代码,查看内部实现,而是联系类作者。对于类作者来讲,正确的做法不是面对面告诉答案,而是去修改类的接口文档
  • 设计和实现
    • 通过包含来实现“有一个”的关系
      • 警惕超过7个成员的类
    • 通过继承实现“是一个”的关系
      • 用public继承
      • 要么使用继承并详细说明,要么就不要使用它
      • 遵循Liskov替换原则,即对基类的子程序,在它的所有派生类上含义都应该是相同的,在调用时只用看基类无需考虑是哪一个派生类
      • 只继承需要继承的部分
      • 只有一个实例的类值得怀疑
      • 只有一个派生类的类也值得怀疑
      • 派生中覆盖了某个子程序,但是其中没做任何操作,也值得怀疑
        • 很可能修改了基类接口的语义,慢慢地从基类接口很难理解派生类上的行为
      • 避免过深地继承:降低复杂度
      • 尽量使用多态,避免类型检查
      • 适度使用继承
        • 多个类共享数据而非行为 => 创建类包含的公用对象
        • 多个类共享行为而非数据 => 都从基类派生,在基类中定义公用的子程序
        • 多个类既公用数据也公用行为 => 都从基类派生,在基类中定义公用的子程序和数据
        • 通过基类控制接口 => 继承
        • 自己控制接口 => 包含
    • 成员函数和数据成员
      • 减少子程序
      • 进制不必要的成员和运算符
      • 减少对其他类子程序的间接调用
    • 构造函数
      • 尽可能早构造函数中初始化所有数据成员
      • 用私有构造函数来实现单例数据
      • 优先使用深拷贝,除非需要,才使用浅拷贝
  • 创建类的原因
    • 为现实/抽象世界的对象建模
    • 降低/隔离复杂度
    • 隐藏实现细节
    • 限制变动的影响范围
    • 建立中心控制点
    • 将相关操作包装在一起
    • 避免的类:万能类、无关紧要类、动词命名类
  • 超越类:包

设计子程序

  • 子程序是为了实现特定目的编写的方法或过程
  • 编写子程序的正当理由
    • 降低复杂度
    • 引入中间、易懂的抽象
    • 避免代码重复
    • 支持派生类覆盖
    • 隐藏指针操作
    • 改善性能
    • 增加可读性
  • 子程序上的设计
    • 一个子程序只做一件事
    • 考虑靠近纯函数或纯副作用函数
    • 内聚性
      • 功能上的、顺序上的、通信上的
      • 避免临时的内聚性(只是需要同时执行才放在一起操作的子程序),如贫血的startup()方法
      • 避免逻辑上的、巧合的内聚性
  • 起个好名字
    • 描述所做的事情,而非做事情的过程
    • 避免使用模糊的动词
    • 不要仅用数字区分子程序名
    • 函数名不要过长
    • 考虑描述返回值
    • 使用预期强烈的动词 + 宾语
    • 使用对仗词,如add/remove
    • 为常用操作统一命名
  • 子程序长度:最好少于100行,可以接受100 - 200行
  • 子程序入参
    • 按输入、修改、输出顺序排列参数
    • 如果子程序使用了相似的参数,考虑让他们的排列顺序一致
    • 删掉没有使用到的参数
    • 不要给入参重新赋值
    • 限制入参数(有的说3个,有的说7个)
    • 考虑给参数名增加前缀、后缀
    • 入参和子程序需要在一个抽象层级下
    • 使用具名参数
  • 宏子程序和内联子程序
    • 将宏表达式整个包含在括号内
    • 一般来讲,是不会用宏代替子程序的
    • 节制使用inline子程序,在确认有性能改进后再使用inline子程序

防御式编程

防御式编程让错误更容易发现和修改,并减小破坏。

  • 断言
    • 主要用于开发和维护的阶段
    • 用错误处理代码处理预期中的状况,用断言处理绝不该出现的状况
    • 避免把需要执行的代码放在断言中
    • 对于高健壮性代码,应该先断言再处理错误
  • 错误处理技术
    • 返回中立值,如空串、0
    • 换用下一个正确数据,如获取温度
    • 返回上一个正确数据,如屏幕重绘
    • 使用最接近的合法值
    • 打印警告信息到日志文件中
    • 返回错误码
    • 显示出错信息
    • 关闭程序
    • 平衡正确性和健壮性
  • 异常
    • 通知程序其他部分,发生了不可忽略的错误
    • 只在真正例外的情况下才抛出异常
    • 避免再构造函数或析构函数中抛出异常
    • 在恰当抽象层次抛出异常
    • 在异常信息中加上导致异常的所有信息
    • 避免空的catch语句
    • 异常标准化 & 异常报告机制
  • 辅助调试的代码
    • 进攻式编程:让问题更早暴露
    • 方便地移除调试代码
  • 保留防御式代码的程度
    • 保留检查重要错误的代码
    • 去掉检查细微错误的代码
    • 保留让程序稳妥崩溃的代码
    • 记录错误信息

伪代码编写

  • 创建一个类
    • 创建类的总体设计
    • 创建类中的子程序
    • 复审并测试
  • 伪代码
    • 使用类似英语的用法描述准确操作
    • 避免使用特定编程语言的语法元素,防止陷入到代码本身的层级上设计
    • 在略高于代码的层次上进行设计
  • 通过伪代码创建子程序
    • 检查先决条件
    • 定义子程序要解决的问题
    • 决定如何测试
    • 在第三方库中搜寻可用功能
    • 考虑错误处理
    • 编写伪代码
    • 将伪代码转为高层次的注释
    • 在注释下填充代码
    • 检查代码是否需要进一步分解
    • 使用lint或编译器检查错误
    • 去掉冗余注释

变量

这一部分深入到代码细节,围绕如何正确使用变量展开。

一般事项

  • 初始化的一些建议
    • 声明的时候初始化
    • 靠近变量使用的时候初始化
    • 考虑对常量使用finalconst
    • 注意累加器和计数器的重置
    • 用可执行代码初始化
    • 检查合法性
  • 作用域
    • 将变量引用点集中起来可以提高可读性,这样可以减少大脑缓存
    • 减少变量的“存活时间”(从第一条引用语句到最后一条)
    • 减少作用域的一些原则
      • 循环开始时初始化循环变量
      • 变量使用前再赋值
      • 对于变量先采用最严格的可见性,再逐渐放宽
  • 持续性
    • 子程序内/手动回收前/程序运行时/持久存储
    • 为变量选择合适的持续性
  • 绑定时间
    • 编码时/编译时/加载时/实例化时/运行时
    • 越晚绑定越有灵活
    • 选择合适的灵活度
  • 和控制结构匹配的数据结构
    • 序列型数据 -> 顺序语句
    • 选择型数据 -> if case语句
    • 迭代型数据 -> 循环语句
  • 变量单一用途
    • 只用作一件事
    • 使用所有已声明变量

取名

取名是个学问。

  • 几个原则
    • 信达雅
    • 以问题为导向,面向目的而不是手段
    • 适当的长度,小于20个字符,大于8个字符
    • 作用域越小,变量名越短;使用较少的变量或全局变量适用较长的名字
    • 使用限定词(如min、avg、max)和对仗词
  • 特定类型的变量名
    • 循环下标:i,j,k,在嵌套循环时建议使用表意的变量名
    • 状态变量:取个比xxxflag更好的名字
    • 临时变量:避免用临时名字
    • 布尔变量:名字要蕴含真假的意义
      • done/error/found/success
      • 不建议使用is前缀
      • 使用表示肯定的名字,理解成本低
    • 枚举变量:缺少组前缀的需要加上前缀
    • 常量:不使用magic number或magic string
  • 组内需要确定一个命名规范
  • 标准前缀
    • 用户自定义类型缩写,UDT缩写
    • 正交化、便于检索
  • 如何缩写
    • 使用标准缩写
    • 去掉非前置元音
    • 去掉虚词,and
    • 去掉无用后缀
    • 使用每个单词的第一或前几个字母
    • 不提倡语音缩写
    • 缩写要能读出来
    • 避免容易看错或读错的字符组合
  • 应该避免的名字
    • 令人误解
    • 具有不同含义但有相似名字
    • 发音相近
    • 出现数字,这是不好的征兆
    • 拼写错误
    • 仅靠大小写区分
    • 使用易混淆的字符,如0o1l
  • 代码阅读次数要远远多于编写次数

基本数据类型

  • 数值
    • 避免magic number
    • 避免除0
    • 避免混合类型比较哦
  • 整数
    • 检查整数除法
    • 检查整数溢出
  • 浮点数
    • 避免数据级相差巨大的数之间的加减
    • 避免相等比较
    • 避免舍入误差
  • 字符串
    • 避免magic string
    • 考虑国际化
    • unicode支持
    • C语言的字符串
      • 注意字符串指针和字符数组的差异
      • 注意字符串长度声明为CONSTANT + 1
      • null初始化避免无结束符
      • 建议使用字符数组
  • 布尔变量
    • 使用布尔中间变量简化复杂判断
  • 枚举类型
    • 带来类型提示和提升可读性
    • 简化修改
    • 作为布尔变量的可扩展性方案
    • 枚举类型的第一个元素留作非法制
  • 具名常量:“参数化”程序
    • 统一使用
  • 数组
    • 确认数组下标
    • 顺序访问元素,不建议随机访问
    • 数组边界点
  • 自定义类型:typedef作为类的轻量级方案

不常见的数据类型

  • 结构体:数据组合,没有行为的类
    • 用前一问:可以用类么
    • 简化数据块操作
    • 简化参数列表
  • 指针:灵活但容易出错
    • 用前一问:有访问器子程序或防御式编程么
    • 标识内存中某个位置某种内容
    • 一般技巧
      • 同时声明和定义
      • 使用前检查
      • 使用前判断内存是否损毁
      • 在提高代码清晰度上,不要节约使用指针
      • 简化指针表达式
      • 正确删除链表中的指针
      • 删除或释放前设为空值
      • 删除前检查是否非法
      • 统一跟踪分配情况
      • 统一在子程序里,集中实现上述策略
    • C++指针
      • 理解指针和引用
      • 指针用于“按引用传递”,const引用用于“按值传递”
      • 使用shared_ptr
    • C指针
      • 使用显式类型
      • 避免强制类型转换
      • 遵循参数传递的*规则
      • 内存分配时使用sizeof()确定变量大小
  • 全局数据:风险较大
    • 用前一问:有更好的方法么
    • 常见问题
      • 多线程重入问题
      • 阻碍代码重用
      • 破坏模块化和智力上的可管理性
    • 使用理由
      • 简化极常用的数据使用
      • 消除流浪数据(调用链中间的子程序不使用数据)
    • 用访问器子程序取代全局数据
      • 在访问前锁定控制
      • 在访问器子程序里构建一个抽象层
      • 对数据的所有访问限制在一个抽象层

语句

在了解了数据视角的变量元素后,这一部分围绕语句组织展开。

直线型代码

  • 直线型代码即按先后顺序放置语句和语句块
  • 必须明确先后顺序的语句
    • 想办法明确展示语句的依赖关系
      • 组织代码
      • 使用子程序名/子程序参数凸显依赖
      • 使用注释
      • 通过断言或错误处理来检查
  • 顺序无关的语句
    • 使代码易于从上向下阅读,避免跳来跳去
    • 将相关语句组织在一起

条件语句

  • if语句
    • if-then语句
      • 先写正常代码,再写不常见情况
      • 不要在if后跟随空子句
      • 看看是不是不需要else子句
    • if-then-else语句
      • 利用布尔函数简化复杂的检测
      • 把常见情况放在最前面
      • 检查是否考虑了所有情况
  • case语句
    • 选择最有效的排列顺序,如执行频率
    • 简化每种case下的操作
    • 最好能搭配枚举类型一起使用
    • 使用default子句检查默认情况或错误
    • 注意有些语言的case会有fallthrough,需要加break
  • 循环语句
    • 分为计数循环、连续求值循环、无限循环、迭代器循环。分别适用forwhileforeach语句
    • 循环控制
      • 应该把循环体看作黑盒子,外围程序只知道它的控制条件
      • 合理判断使用forwhile的地方
      • 尽量避免空循环
      • 循环内务(包括索引增加)要么放在循环开始,要么放在循环最后
      • 让循环终止条件看起来明显
      • 不要为了终止循环改动for循环的下标
      • 小心散布了很多break的循环,小心谨慎使用breakcontinue
      • 检查循环端点是否会有off-by-one的问题
      • 在嵌套循环中使用有意义的变量名增强可读性
      • 循环要尽可能短,便于一目了然
      • 把嵌套限制在3层以内

不常见的控制结构

  • 多处返回:指程序中途的return或exit
    • 只在能增强可读性时,使用中途的return
    • 用防卫子句提前退出,简化复杂的错误处理
    • 减少程序中的return数目
  • 递归:将复杂问题分而治之
    • 确认终止条件
    • 使用安全计数器防止出现无穷递归
    • 把递归限制在一个子程序里,避免循环调用
    • 留意栈空间
    • 可以用循环结构等价式的先考虑循环结构,如阶乘和斐波那契数列
  • goto
    • 反对随意使用goto
    • goto灵活度太高,不容易用好,在可以使用其他控制结构时,不使用goto
    • 在错误处理中,可以用状态变量、try finally语句实现跳出正常流
    • 如果在那1%的情况下需要使用goto,注意以下几点
      • 尽量一个子程序只使用一个goto
      • 尽量向前跳转而非向后
      • 确保所有的goto标号都被执行到
      • 确认goto不会产生执行不到的代码

表驱动法

表驱动法是空间换时间的一种编程模式,使用数据结构模拟逻辑结构,将大部分复杂度放到容易被理解的数据结构中,从而提升代码可读性。下面是一个代码范例。

1
2
3
4
5
6
7
8
9
10
11
12
13
if ((('a' <= inputChar) && (inputChar <= 'z')) ||
(('A' <= inputChar) && (inputChar <= 'Z'))) {
charType = CharacterType.Letter;
}
else if ((inputChar == ' ') || (inputChar == ',') ||
(inputChar = '.') || (inputChar == '!') || (inputChar == '(') ||
(inputChar = ')') || (inputChar == ':') || (inputChar == ';') ||
(inputChar = '?') || (inputChar == '-')) {
charType = CharacterType.Punctuation;
}
else if (('0' <= inputChar) && (inputChar <= '9')) {
charType = CharacterType.Digit;
}

使用一个查询表建立每个字符和它的字符类型的关联后,代码可以简化为

1
charType = charTypeTable[inputChar];
  • 查表方法
    • 直接访问:如查询每月天数,或不同年龄对应的保险费率
      • 有的时候键值要预先处理后才能直接使用,如可能很多年龄对应相似的费率,这时最好先将年龄换算到一个更好的key上
      • 进一步,我们可以把键值转换提取为独立的子程序
    • 索引访问表:和直接访问的区别在于,对于不易换算到键值的情况,提供一个额外的索引表,先映射到索引表再查到数据
    • 阶梯访问表:主要针对表中的记录是对数据范围而非数据点生效的情况,使用端点作为key
      • 留心端点带来的off-by-one情况
      • 可以使用二分查找代替顺序查找
      • 也可以使用索引访问技术

一般性问题

布尔表达式

  • 使用truefalse作判断
  • 简化复杂的表达式
    • 使用中间变量或布尔函数
    • 使用决策表替代复杂的判断逻辑
  • 编写肯定的布尔表达式,会让布尔表达式更易理解
  • 用括号分割较长的布尔表达式
  • 注意短路求值或惰性求值的情况
  • 按照数轴的顺序编写数值表达式,类似MIN_VALUE <= i and i <= MAX_VALUE,可读性好很多
  • 在C语言中最好把常量放在左边
  • 注意区分Java中a==ba.equals(b)

空语句

  • 小心使用
  • 使用doNothing()函数或noop()函数
  • 考虑能否换用非空的循环体

优化深层嵌套

  • 优化重复的if检查
  • 使用break简化嵌套if,如防卫子句
  • 转换成一组if-then-else结构
  • 转换成case语句
  • 将深度嵌套的语句抽离成子程序
  • 借助多态
  • 借助异常来跳出正常流

结构化编程

结构化编程的思路是仅使用顺序选择迭代的思路描述程序流,避免使用breakcontinuereturntry-catch来打断。

降低复杂度

  • 程序复杂度的一个衡量标准是,为了理解程序,必须在同一时间记忆的智力实体数目,即理解程序花费的精力
  • 控制流的复杂度和不可靠的代码以及频繁出现的错误息息相关
  • 可以通过计算子程序的“决策点”粗估子程序的复杂度
    • 从1开始,遇到ifwhilerepeatforandor加一,为每一种case加一

2018-2019: https://shenlvmeng.github.io/blog/2019/01/03/2018-to-2019/
2019-2020: https://shenlvmeng.github.io/blog/2020/01/04/2019-to-2020/
2020-2021: https://shenlvmeng.github.io/blog/2021/01/05/2020-to-2021/

从19年初写下第一篇总结到现在,已过去近3年,每年写总结时,都会发现计划永远赶不上变化,惊喜总在发生,也总能体验这辈子从未经历过的一些事情。就像在超市购物时推着一辆磕磕巴巴的小车一样,正反馈的前进路线需要不断地人为纠正。最终走出一条弯弯曲曲却通向想去方向的路线。

世事难料,2021年尤其是个例外。我目送了朋友的离开,见证了忠贞的新人携手相拥,告别了早该舍弃的人,与老朋友重逢,来到陌生却熟悉的新城市,拥抱了所爱也爱我的人,认识又立马和新朋友告别,开启看起来模糊却又无比清晰的未来道路。生活逐渐健康,生活更加明亮,生活逐渐充满期望。不过总有些不变的,譬如固定的长途骑行,以及在间歇性踌躇满志和间歇性混吃等死中间徘徊。

2021回顾

比照去年目标,在内在上,看完了4本技术书籍中的2本,以及剩余10本小说中的8本:

剩余的2本,devops读至一半,深感信息量之少,收获甚少,弃之。《代码大全》则由于过厚暂时搁置。不过,在某leader的启发下,对管理学产生了兴趣。从推荐的《领导梯队》和《赢》入手,接触到德鲁克的一些观念:

经过这几本的洗礼,感受到管理学绝不仅仅是日常的事务性管理动作。而有一整套价值观和方法论,如依人办事等。看完之后大开眼界,颇有些屠龙之术的意思。这也许只是我屁股不在目标人群中吧。于是剩余的两本德鲁克及时叫停,回到追求实用的现实世界。在技术以外了解一些其他领域的知识,启示挺大。

个人形象上,除了改成推平的毛寸(以及发胖)之外,几乎没有任何变化。发胖这点,也不能完全赖我,和对象也有一定关系。早睡早起这点倒是因为和对象同住坚持得很好,这大概是今年最大的进步了。锻炼频率从来了上海之后有所下降,等到对象回到附近之后预期会好很多。整体看,发胖这点还是要重视的。

社交上,来到上海后,除了老朋友外,倒是拾起了一些很久未联系的“新朋友”。情感上,很庆幸地,经过身边亲朋好友的轮番劝导和自己的冷静思考,让我及时从糟糕的关系中摆脱出来。谢天谢地,又让我遇到现在的她。说来奇妙又激动。2021年似乎在5月份和6月底开启了两次新篇章。之后整个下半年局面大为不同。经过艰难又忐忑的4个月异地,辛苦却又自然地合体。一切仿佛都是最佳的选择。

生活上,业余时间基本都是和对象一同。不过俩人的兴趣爱好相仿,骑车和看电影都能一起,因此这两点并没放下。在今年5月份开启新篇章后,斥巨资换了现在的新公路车,大大提升了骑行体验,不得不说真能买到快乐。之前的公路车刚好可以给对象骑。尽管11月才结束异地,已经一同骑了快10次了。魔都的骑行路况尽管比不上帝都,气温相对帝都还是要温柔一些。照例,今年完成了环太湖之旅,一路上经过苏州、无锡、宜兴、湖州、南浔,也算是满足了圣僧一路江南城市的愿望。清理完已有的洋酒库存后,小酌频率的确下降很多了,可惜对象酒量很差,平日只能看我表演。旅行上,在偶发疫情的情况下,和对象国庆去济南青岛转了一圈,十月底被痛仰两放鸽子后,得到了宝贵的杭州一日游。搬到和对象同居之后,俩人分工,一人负责干净一人负责整洁,整个房间倒是窗明几净、井然有序。平日周末一同下厨或探店或社交,不亦乐乎。livehouse倒是计划了好几次,可惜疫情人算不如天算,至今未能看到。

事业上,借助大方向的发展势头,年初得到了意料之外情理之中的提升机会。赶在行业腰斩个人选择导致的发展减缓前,获得此等良机,可以说很幸运了。而后随着来到魔都,第一次感受landing流程和新leader磨合,另外团队也有所扩张,十分难得。可惜由于公司政策调整,结合个人意愿选择,放弃了这个良机。去向了一个完全陌生的领域,极大提升通勤体验的同时,牺牲了先发优势。正如那位leader所说,“既然是去一项成熟的业务,最好提前降低下预期”,因此也做好了发挥空间有限,要重新建立信任的准备。有挑战才有意思嘛。也希望在来年能有所成果。结合管理学阅读还有某leader的1on1,在职业规划和发展路线上有了一些粗浅的想法。在和对象的交流下,了解到内卷业务的可怕,还有外企的香甜,不由得内心也心向往之。作为一项国际化业务,这里倒是也可以当做未来的跳板吧。何时才能成长到在外企大厂带人做事的程度呢?

至于落脚城市,就这里吧,也挺好。下一阶段,就是房子、车子、票子的事情了。有了可以一同踏踏实实的人,也放心去想踏踏实实的事儿了。

2021总结

  • 仰望星空的同时,脚踏实地也很重要
  • 保持身体健康
  • 减肥要提上日程
  • 生活中总会发生不公平的事情,不过整体来看,它还是公平的
  • 少吃一口饿不死,多做一点累不死
  • 迈出第一步,事情就会慢慢发生,就像在山顶推一个石头
  • 事业上,成果导向,用人所长,因人成功
  • 工作中有些事情,功夫在诗外,人际关系也很重要
  • 要开始考虑一些更长远更现实的事情,比如买房、养老、医保,做一个合格的父亲

2022展望

好了,写计划和期望的时候总是心情舒畅。下面列出一些期望,

  • 内在
    • 完成代码大全和至少一本专业书籍的阅读
    • 完成剩下所有小说阅读
    • 探索一个新的领域,形成积累
  • 外在
    • 控制体重回到80kg
    • 坚持早睡早起早饭
    • 坚持一项骑行以外的运动,如游泳
    • 升级对象骑行体验
  • 生活
    • 至少1次和对象的旅行
    • 至少1次户外长途骑行
    • 学习3种硬菜
    • 至少1次livehouse
    • 控制饮酒频率
    • 享受探店
    • 更好地融入魔都
      • 社保、户口
  • 社交
    • 和对象相互认识老朋友
    • 回一次家 & 去一次沈阳
  • 事业
    • 做出一项成果
    • 能在所在业务下带小团队

凡是经历没经历过的事情,都是好事。预知后事如何,明年拭目以待。

Bye~

deep link是指可以从任何渠道,包括短信、应用内、网页中直接跳转到应用app内的特定页面的技术。它一定程度上打破了移动端app间“孤岛”的局面,实现了快捷的跳转。根据是否安装app,主要有下面两种行为:

  • 已安装,唤起app并跳转到特定页面
  • 未安装,跳转到App Store或下载页面引导用户下载安装,在下载后的第一次打开自动跳转到特定深度页面,这种情况也叫deferred deep link

deep-link-info

场景

deep link可以应用在很多常见的场景下,如

  • 社交分享
  • 广告引流
  • web和app互通
  • 裂变活动
  • 短信、邮件营销

在web和app互通场景下,可以很方便地实现从外部回流页回到app内特定位置,如:

  • 电商类app:分享H5跳转到特定商品页
  • 游戏类app:分享H5跳转到特定房间或任务
  • 直播类app:分享H5跳转到特定直播间

deep link缩短了操作路径,减少了用户操作成本,从而降低用户流失率,帮助app拉新和留存。

实现方式

常见的实现方式有下面几种

  • URL scheme,iOS和Android下的通用方式,打开前会询问是否打开某app
  • Chrome Intent,Chrome 25+无法通过URL scheme 唤起 App,必须使用Intent
  • Universal Link,适用于iOS 9及更高版本,点击http/https即跳转,操作丝滑
  • App Links,适用于Android 6及更高版本,点击http/https即跳转,操作丝滑

除了上面几种,还有Smart App Banners、剪贴板等方案

URL scheme

格式形如[scheme:][//authority][path][?query][#fragment],一般使用在iOS 9和Android 6之前。方法通用,但有以下问题:

  • 本身没有规范,难以获知要跳转的path或query
  • 功能不全,app越复杂,scheme就越复杂
  • 会被拦截,包括浏览器或应用的webview,如微信
  • 打开app失败后,iOS会有错误弹窗,体验不好
    • 提示网页无效
  • URL scheme可能重复

常见Scheme URL

微信 电商 浏览器 系统 其他
weixin://dl/scan 扫一扫
weixin://dl/moments 朋友圈
weixin://dl/settings 设置
淘宝:taobao://
支付宝:alipay://
美团:imeituan://
Chrome:googlechrome://
UC 浏览器:ucbrowser://
邮箱:mailto://
短信:message://
App Store:itms-appss:// macappstores://
飞书:lark://
微博:sinaweibo://

Chrome Intent

Chrome 25+无法通过iframe的src启动Android app。改为构造形如下面的intent锚点。

1
2
3
4
5
6
7
8
9
intent:  
HOST/URI-path // Optional host
#Intent;
package=\[string\];
action=\[string\];
category=\[string\];
component=\[string\];
scheme=\[string\];
end;

end前添加S.browser_fallback_url=[encoded_full_url]可以指定唤起失败的地址。一个构造好的intent形如:

1
intent://path#Intent;scheme=xxx;package=com. xxx;S.browser_fallback_url=https://xxx;end

官方介绍

Universal Link,即通用链接,是iOS 9推出的通过HTTPS链接来启动app的特性。既可以打开app,在没有安装时,则打开特定网页。对比URL Scheme优势在于:

  • 无缝切换,不弹窗确认
  • 兼容性好,未安装时直接打开网页
  • 使用通用的HTTP协议,不用担心scheme重复
  • 通过网站的配置文件和app关联,保证安全

在网站下根目录或.well-known路径下需要有apple-app-association(无后缀名)JSON文件。例如,知乎的配置文件为https://oia.zhihu.com/apple-app-site-association。在配置时,

  • 需要保证有一个HTTPS的域名,最好和web网页域名区分开,保证web网页的正常访问
  • 在开发者中心 ,Identifiers下 AppIDs 找到自己的App ID,编辑打开Associated Domains服务
  • 打开工程配置中的 Associated Domains ,在其中的 Domains 中填入你想支持的域名,必须以applinks:为前缀
  • 配置apple-app-site-association文件,不带任何后缀,上传该文件到服务器的根目录或者.well-known目录下

在网站下配置好Universal Link后,用户点击网站链接后,即会直接跳转到App,而不需要经过浏览器。当然,微信等app还是会拦截Universal Link的行为,需要在微信注册自己的应用id和Universal Link。

官方介绍

App Links,类似Universal Link,是Android 6(Android M)及以上操作系统中适用的HTTPS路径链接。可以直接将用户带入到Android app内的特定页面中,实现上,网站配置文件名为assetlink,只能放在.well-known目录下。如https://vt.tiktok.com/.well-known/assetlinks.json。不过,国产的安卓版本以及微信等app依旧会拦截。

其他

  • Android webview本身支持唤醒第三方app,但如果设置了自定义WebViewClient则需要自己处理,具体是指在shouldOverrideUrlLoading方法中决定如何处理
  • Smart App Banners,在网页里增加一个<meta>标签,可以在打开页面时,检测手机是否安装某个app,并且在页面顶部显示一个Banner显示App的基本信息,安装时显示打开,未安装时显示安装

相关产品或开源库

结合点击行为、重定向行为、来源去向分析、落地页等,还可以做很多事情,市面上也有下面一些产品:

另外,也有一些开源库实现web跳转app

–END–

与其说德鲁克是管理学鼻祖,他更像在研究社会、组织、企业存在的合理性与最佳实践。德鲁克认为人性是不完美的,那人设计出来的社会也不可能完美。他抵制极权专制,这里的极权不同集权,所追求的是全面彻底地操纵和控制人类的每一个成员。德鲁克视管理学为一种“博雅艺术”(liberal art)。它既不像人文文化,也不像科学文化。它关心人的价值成长和社会组织的影响,但又关心管理工作的应用的成果。这使得管理学不像世俗观点中的那样,是一个人或一个机构的成功学。它只在让每个人在社会和社群中更健康,自由地选择并履行承担的责任,从而是人类社会和社区更健康,人们受到更少的伤害和痛苦。

而这本书即从管理者的成效出发,探讨一个管理者如何能管理好自己。毕竟让一个自身成效不高的管理者管好他下面的下属,几乎是不可能的事情。而卓有成效的管理者也逐渐成为社会中的关键资源。

卓有成效可以学会

卓有成效重要且可以学会

  • 首先端正思路,管理者为什么必须有效
    • 有效即“做对的事情”,而不是纯执行的“把事情做对”
    • 当下知识工作者逐步增多,他们产出的更多是抽象的知识、创意或信息,无法用传统衡量体力活动的方式衡量,因此需要自己管理自己,自觉做出贡献,追求工作效益
  • 谁是管理者
    • 如果在组织内,一个知识工作者,能够凭借职位或知识,对组织负有贡献的责任,因而能对组织的经营能力或成果有实质性影响。那他就是一位管理者。
    • 衡量知识工作,主要应看结果而不是工作繁杂程度
    • 一般的经理人员工作性质和董事长、政府机构的行政领导是相同的,那就是计划、组织、整合、激励和考核
  • 管理者的不利现状
    • 组织的管理者会面临下面一些压力
      • 时间往往属于别人,不属于自己,如经常有外部人员拜访
      • 往往被迫忙于“事务性工作”,除非他们敢于采取行动改变周围的一切
        • 管理者需要一套判断体系,去找到真正重要的事项
      • 管理者的贡献能被其他人利用时,才算有效
        • 组织是使个人才干能够增值的工具,一个人的知识可以被组织吸收,作为其他知识工作者工作的资源
        • 贡献不能被有效利用时,有效性也会打折扣
      • 管理者会受到组织的局限
        • 受到的信息会被组织过滤
        • 组织需要为外部服务,因此需要得到外部的信息
        • 组织是社会中的人为产物,和生物体类似的是,成长得越大,消耗的资源和复杂度就越大
    • 对外部信息的收集,人从现象中的抽象能力往往优于机器(类似深度学习)
  • 提高有效性,让工作达到令人满意的程度
    • 不要期望万能的天才来达到绩效,通才难求,学会善用专精于某一领域的人
    • 通过从各种有效的管理者归纳来看,他们各个方面都不完全一样,人人都具有做好该做事情的能力,即有效性
    • 下面一些习惯是成为卓有成效管理者所必须的
      • 善用时间,知道时间都去哪儿了
      • 重视对外界的贡献,目标导向
      • 善于利用长处
      • 集中精力到少数重要领域
      • 敢于、善于做决策

掌握自己的时间

时间是最珍贵的资源,先摸清自己的时间分配,再统一管理和安排。

  • 所有资源里,时间不像资金、人力,是最稀有毫无可替代性所有工作必须消耗的资源,而人往往不善于使用这种资源
  • 管理者面临的时间压力
    • 管理者作为知识工作者,他的大多数任务,都需要相当多的整块时间
    • 管理者要与他人一同工作,需要各种信息,需要讨论、需要指导他人,需要协调人际和工作关系,这些都是费时的
    • 只有在脑力上多费时,才能在体力上少费时
    • 如果时间短促,一个人就只能考虑他已经熟悉的事,做曾经做过的事,无法创新和变革
  • 你诊断过你的时间么
    • 第一步是记录时间的耗用情况,一定要当即记,事后回忆往往不准确,然后问下面一些问题
    • “什么事情根本不必做”
    • “哪些活动可以由别人代为参加”,学会授权
    • “有浪费别人的时间么”,如过多的会议
  • 消除浪费时间的活动
    • 找出可以通过制度或远见避免的时间浪费
      • 一个平静无波的工厂,必然是管理上了轨道,因为所有危机都已预见,并变成了例行工作
    • 人员过多会带来人际关系的时间浪费
    • 组织不健全,表现就是会议太多
      • 之所以要开会,是因为某种情况的所需的知识不能装在一个大脑里
      • 要开会,也要有计划
    • 信息功能不健全,上下文不透明,或信息表达不当
  • 统一安排可以自己支配的时间
    • 高级主管可以自由运用的时间,可能只有1/4,组织越大,维系组织运行而不是发挥组织价值的工作越多,从而不由自己掌控的时间越多
    • 可以给自己的时间划分最小单位,如90分钟,聚合碎片时间
    • 对时间的控制和管理不是一劳永逸的,要不断记录时间消耗并分析

我能贡献什么

关注产出,目标导向,可以帮助自己thinking out of the box。

  • 重视贡献,注意对成果负责,才能看到整体的绩效
    • 只有这样,一个人才能考虑自己的技能、专长和整个组织以及组织目标的关系
    • 管理者如果不自问“我可以做出什么贡献”,在工作中就不会有远大的目标,而偏向执行的角色
  • 一般机构对成效的要求往往有下面三个方面
    • 直接成果
    • 梳理新的价值观或对价值观的重新确认
    • 培养和开发明天所需的人才
  • 职位越高,对外所需的贡献就越大
  • 对于专业人员,必须使自己的“产品”——即他的只是可以为别人所用;同时,肩负贡献的责任,要求他知道应该了解别人的需要、别人的方向,别人的理解,从而使别人能够应用他的成果
  • 有效的人际关系有4项基本要求,而着眼贡献正可以满足
    • 以目标为导向,可以很方便对齐期望,有助于互相沟通
    • 强调贡献有助于横向沟通,促成团队合作
    • 个人发展,一定程度上也要看是否重视贡献
    • 重视贡献的管理者必然能启发他人寻求自我发展,从而培养他人
  • 重视贡献,才能使管理者的视线从“内部事务”转向“外部世界”

发挥他人长处

人无完人,有效的管理者可以使人发挥长处,减少短处带来的限制。

  • 世界上从来没有发生过下属的才干反而害了主管的事
  • 人的精力有限,卓越通常只能表现在某一或者某几方面
    • 是用人来做事,不是用人来投自己所好,或投主管所好
    • 有效的管理者从来不问“我和他能合得来吗”,而是问“他能贡献什么”,从来不问“他不能做什么”,而是问“他能做什么”
  • 要坚持因事用人而不是因人设事,这样才能减少组织变动,同时保证以任务为重心,而不是以人为重心
    • 只有极少数例外,譬如有特殊才干,从事非一般工作,取得杰出成就的人
  • 能建立一流经营体制的管理者在公事上,通常会和周围同事以及下属保持一定距离,避免个人好恶挑选人才
  • 如何做到发挥长处,同时避免因人设事的4个原则
    • 一个职位,如果先后多人担任都失败了,那肯定是常人无法胜任的职位,需要重新设计
      • 国际部副总裁的压力,需要由按产品类别调整组织,或是按市场的社会经济背景调整组织来合理规划
      • 只有让“平凡人做出不平凡事”的组织,才是好组织
    • 职位要求要严格,涵盖要广(想象空间大)
      • 从而保证下限高,人才又有能充分发挥的机会
      • 知识工作者的职位设计,还应该能够让人及早发现自己是否适合该职位
      • 与体力劳动者不同,知识工作者的贡献产出不仅和本身的知识技能有关,和组织的目标、价值观也有很大关系
    • 用人时,先考虑某人能做什么,而不是职位的要求是什么
      • 在考评、绩效制度上,更多从“某人能完成什么”的视角看问题
        • “哪方面的工作他确实做得很好”
        • “哪方面的工作还可以做得更好”
        • “为了充分发挥长处,他还可以再学习什么知识”
        • “如果我有了子女,愿意让子女在他的指导下工作吗,为什么?”
      • 正直的品格很关键
    • 必须能容忍人的缺点
      • 结合具体任务来寻找别人的长处
  • 用人所长是有效管理者的必备素质,也是组织能否有效的关键
  • 卓有成效的管理者还会设法发挥上司的长处
    • 不能唯命是从,需要协助上司发挥所长,也能给自己更大的空间
  • 也要了解自己的长处,寻找适合发挥自己长处的工作方式,做出自己的绩效
  • 管理者的任务不是去改变人,而是在于运用每个人的才干

要事优先

时间有限,做重要的事;而立足现在看未来才可看到真正重要的事情

  • 时间总是不够,只有几种个人、组织的所有才干,才能获得成果
  • 一次只做好一件事,恰恰能加快工作速度
    • 我们往往会低估完成任务的时间
  • 很多组织都容易错误地看待过去的成功和失败
    • 当下的很多计划和制度,是基于过去的经验确定的,时间久了已不能产生成果
    • 及时重构,去肥增瘦;只有推陈才能出新
  • 对于新工作,应责成确能证明有能力的人来负责
  • 所谓压力,总是偏爱机构内部的事务,偏爱已经发生的事而忽视未来,偏爱危机忽视基于,偏向急功近利而忽视现实世界
  • 真正的难度不在决定做什么,而是什么可以缓一缓
    • 被搁置一般等同于被取消,因为外部世界变化极快
    • 下面有一些可以确定事情优先顺序的原则
      • 将来 > 过去
      • 重视机会,不要只看到困难
      • 选择自己的方向不盲从
      • 目标要高,要有新意,不能只求安全和容易
  • 化机会为成果,肯定比解决旧问题更有生产性。解决旧问题,不过是恢复昨天的平衡而已

决策的要素

管理者要做对组织绩效有效果的决策,决策是观念性、战略性的,不是细节的、解决问题的。

  • 一项决策如果不能付诸行动,就只能算作想法
  • 贝尔公司的费尔和通用汽车的斯隆,解决问题,都着眼于最高层次的观念性认识,所做的决策不是为了适应当时的临时需求,而是战略性考虑
  • 决策有下面一些要素
    • 判别问题性质
      • 一般遇到的问题可以分为四类
        • 表面现象之下的真正经常性问题
        • 特殊情况下偶然发生的实质上经常性问题
        • 真正偶发的特殊事件(“黑天鹅事件”)
        • 第一次出现的“经常事件”
      • 对于经常性问题要有经常性的解决办法——一种规则、一种政策或一种原则
      • 判断问题性质并没那么简单,可能遇到一些常见错误
        • 把经常性问题视为一连串的偶发问题(“实用主义”)
        • 将真正的新问题视作旧病复发,从而采取错误的方法
        • 对根本性问题界定似是而非
        • 只看到问题局部,没看到全貌
      • 一个有经验的管理者总会先假定问题只是表面现象,从最高层次的观念方面寻求解决方法。他要找出真正问题,不满足表面现象,从更基本、更理性、更广泛的观念上谋求解决办法
    • 找到解决问题的限制条件或假设前提
      • 边界条件往往不容易找到,因为每个人的视角不同
      • 错误的边界条件,比没有更误事
      • 边界条件清晰时,有助于决策人在情况变化时,更快用新决策取代旧决策
      • 依赖太多边界条件去决策是危险的
    • 考虑问题的正确方案,之后再考虑必要妥协或让步事项
      • 如果一开始就问“什么是能让人接受的决策”,那永远不会有结果
    • 决策要兼顾执行措施
      • 必须能准确无误地回答下列问题
        • 谁应该了解这项决策(object)
        • 应该采取什么行动(what)
        • 谁采取行动(subject)
        • 行动如何进行(how)
    • 重视反馈,验证决策的有效性
      • 决策是会过期的,需要建立反馈机制更新决策

有效的决策

一项决策若要保证有效,需要考虑各种方案,甚至包括反对意见。另外,电脑不能取代管理者做决策,反而会让更多人参与到决策中。

  • 决策不是从搜集事实开始,而是先有自己的看法和立场,再去搜集事实证明
    • 搜集事实本身就会预设立场,做不到客观
    • 大胆猜测,小心求证:假设和见解不必辩论,鼓励大家提出,但是必须经过深思,必须经得起验证
  • 如何衡量决策,需要的时间和经历也极多
    • 使用反馈的制度
    • 只有有多项方案,从中选择一项,才能称得上判断
    • 管理者一定要先有若干种不同的衡量方法,再从中选择最合适的一种
  • 好的决策,应该以互相冲突的意见为基础,从不同观点和判断中选择
    • 反对意见相当重要
      • 唯有反对意见,才能保护决策者不至沦为组织的俘虏
      • 反对意见不深,也可以作为决策的“另一方案”
      • 反对意见可以激发想象力和创造力
    • 当然世上有蠢材和恶作剧的人,不过有效的管理者会假定,某人意见纵然错了,也是由于此人看到的现实不同,或者关注的问题不一样
  • 是否真的需要一项决策
    • 满足下面两项原则即可
      • 利益远大于成本或风险就该做
        • 不要做鸡毛蒜皮的小事,也不要墨守成规
      • 行动或不行动,切忌只做一半或折中
  • 决策前,想清楚规范、不同方案、得失也衡量了,采取什么行动也想好了。尚未想清楚前,不要冒冒失失地决策,但都想好了,也绝不会优柔寡断
  • 电脑只是工具,人类则不是逻辑的,而是具有感官的;电脑所做的决策是预先安排的,不能随机应变,都是基于硬性原则
  • 每一位知识工作者有效决策能力的高低,决定了其工作能力的高低

总结

全书内容无非两点:

  • 管理者的工作必须卓有成效
  • 卓有成效可以学会

做到卓有成效需要从几个方面努力:

  • 记录好时间的使用情况,分析时间记录,消除不必要浪费
  • 集中眼光在贡献上,从执行进入到观念,关注个人目标和组织目标的关联
  • 充分发挥人的长度,融合个人能力和组织成果
  • 做重要的事情
  • 有效的决策,合理的行动

今天的组织需要的是平凡人做不平凡的事业。组织取得好的成效,要靠组织中的人切实进行系统化、专门化的自我训练,成为有效的管理者。在如今,知识工作者为组织服务,除了物质上,在心理需求和个人价值上也需要从工作和职位上获得满足。因此,一定要使组织绩效和个人成就结合起来。管理者在卓有成效上的自我提高就是唯一解法。

关于管理和商业化这个大话题,《赢》这本书从“术”的角度,结合自身几十年的成功经验,给出了自己的看法和建议。书中的视角不像《领导梯队》一样,切入到很实际的角度,很具象地描述和推广领导力模型。《赢》的视角要更为大和全面,在管理上更实用。同时,相对德鲁克的管理学著作对于组织、管理的系统探讨,《赢》又更实用和大杂烩一点,不仅介绍了公司的管理技巧,也讲解了公司竞争、个人发展相关的一些商业手段。整体值得一看,可以开拓自己的做事思路,文本精简而平易近人,很易读。

原则篇

韦尔奇从先从自己的经营方式中,总结出4个基本原则,作为后续实践的基础:

  • 使命和价值观
    • 有效的使命需要有清晰的方向,以赢的商业利益为导向,又要让人充满雄心壮志
      • 例:成为世界上最有竞争力的企业,即各个业务领域都在第一或第二的位置
    • 确定使命始终是企业高管的职责
    • 价值观体现在人的行动,是具体的、本质的、可以描述的
      • 让员工参与进来
      • 具体的价值观念和行动纲领
      • 反复实践修正
      • 配合奖惩
    • 使命和价值观需要融为一体,出现偏离时,通常是因为商业生活中出现了危机
  • 坦诚
    • 坦诚可以减少沟通负担、鼓励信息流动、减少沟通中的信息损耗或走样;从而吸引更多人参与对话、提高效率、节约成本
    • 坦诚使人紧张,这是人们的世故带来的,
    • 鼓励坦诚是项艰难而费时的工作,
      • 要普及坦诚,需要不断激励、赞赏、谈论它,还需要自己带头,同时展示给别人看
  • 考评
    • 考评不过是资源配置而已,将资源投放到回报最丰厚的地方,避免不必要的损失
    • 可以将员工分为最好的20%,中间的70%,最差的10%
      • 最好的20%:大加鼓励,基于物质和精神财富
      • 中间的70%:培训教育、积极反馈,分辨哪些人有提升潜力
      • 最差的10%:“不是人人都能成为优秀的棒球手”
    • 需要坦诚和清晰的流程来保证
      • 清晰的期望值、目标和时间表
    • 在商业生活中,积极向上且外向的人通常能做得更好,得到更多偏爱
  • 发言权和尊严
    • 人们都希望得到发言权和尊严
    • “对于讨论会上的75%的建议,需要现场给出‘行’或‘不行’的回答;剩下的25%要在30天内回答”

公司管理

下面6章主要介绍公司管理的有效手段

领导力

在你成为领导者之后,你的成功和他人的成长有关。有下面一些准则评估一个领导者的领导力:

  • 坚持不懈提升自己团队,珍惜每一次oneone的机会
    • 必须做好评估、提供指导、树立员工自信心
  • 让员工心怀梦想,实践梦想
    • 保持和公司同步
  • 深入员工中,传递积极活力
    • 一个团队的风格会受到领导的影响,积极的领导才能带出积极的团队
  • 以坦诚、透明度提升自己的可信赖感
    • 坦诚、言出必行
    • context, not control,激发潜能
  • 有勇气作出决定
  • 用好奇心和怀疑精神监督业务,要习惯于提问题,不放过问题
    • 适当的challenge可以让员工更深入本质
  • 用于承担风险和学习
    • 对于比自己优秀的下属,要向他们学习
  • 学会庆祝

招聘

招聘的员工可以怎么考察。

  • 3项考验
    • 正直:说真话、授信、知错能改
    • 智慧:有求知欲和知识面
    • 成熟:能够控制情绪,尊重他人情感
  • 4E1P人员招聘方法
    • Energy:积极向上的人热爱生活
    • Energize:能激励人,鼓舞自己的团队
    • Edge:需要能做出果断的决定
    • Execute:有执行力,能落实工作任务
    • Passion:有旺盛的生命力和激情
  • 招聘高层人士的额外特征
    • 真诚:需要保持本色,没有伪装
    • 对变化来临的敏感性
    • 爱才:即希望周边人更优秀和聪明
    • 强大的韧性,不怕失败,能屈能伸
  • 招聘管理职位时,至少需要有前两个E
  • 招聘人才时,要更看重长远的发展潜力,努力寻找能和业务一同成长或者能到更高职位的人才
    • 在招聘员工时,不要提供他们职业生涯的“终极岗位”
  • 询问上一次的离职原因通常可以获取到绝大多数你想了解的信息

人员管理

对于按上章标准招聘来的人才,可以有下面一些管理准则:

  • 重视人力资源管理,人力资源管理人员可以帮助经理人培养领导者
    • 人力资源管理应当与公司其他业务一样重要
    • 出色的人力资源经理,既是牧师又是父母,既能倾听,又能给与关爱和教育
  • 采用一套严格、非官僚的业绩评价体系
    • 简洁明了的评价
    • 和行为相关联的标准
    • 每年一次到两次
    • 应当包含职业发展的内容
  • 有一个激励机制,包括物质上和精神上的
    • 和奖赏一样,培训也有同样的激励作用
  • 积极处理和工会明星员工边缘分子捣乱分子的关系
    • 工会:正直和积极的态度,有原则
    • 明星员工:提前考虑可替代性
    • 边缘人员:拉回正轨或者及时辞退
    • 捣乱分子:限期改正或及时辞退
  • 不要忽视70%的大多数
  • 设计更扁平和更易懂的组织框架

解雇

既然有招聘,当然就有解雇。解雇分三类:

  • 违法或者违反道德准则而遭解雇
  • 因为大环境或经济问题的裁员
  • 因为业绩不佳的解雇

对于第一种,不需要解释,当机立断即可。对于第二种,需要让员工提前知道公司的经营情况,从而有提前的心理准备。对于第三种,主要在于降低员工的羞耻感,给一个缓冲时间,尽量做到:

  • 留下缓冲时间:给人心理准备
  • 坦诚清晰:减少误解,直说事实,无需粉饰
  • 及时say goodbye:拖得太久会影响团队的稳定性

改革

公司要能适应外界变化和自身情况,积极调整自己,这即是改革。

  • 如果你认为需要改革,但是却不具备权威,那就提出自己的议案,你的建议如果没得到响应,那么要么接受现状要么离开
  • 设立清晰的目标和指标,不要为了改革而改革
    • 收集bad case
    • 远离空洞口号,立足实际的行动
  • 招募和提拔支持者
    • 这类人通常以“卷王”的形式出现
  • 清理反对者,尤其是在他们构成阻碍的时候
  • 抓住良机
    • 黑天鹅事件无时无刻都在发生

危机管理

解决危机可能是每个管理者不愿面对,却又不得不面对的事情。下面是这一章中提到的一些tips:

  • 假设问题本身比表现出来的更糟糕
    • 降低预期,饱和式补救
  • 假设所有人最终都会知道事件真相
    • 要坦诚错误,但也不要将所有错误都包揽在身上,保证说得都是事实就行
  • 假设你和所在组织会被人用摸黑的态度描述出来
    • 在别人全面曝光之前,如果不能奋起反抗,为自己辩护,那就只能被别人埋葬了
  • 危机处理中,总要有人付出代价
    • 危机后总有变革发生
    • 有人需要对发生的事故承担责任
  • 假设你的组织将从危机中恢复,并变得更强大
    • 就像免疫系统一样

赢得竞争

不同于上一部分,这一部分在管理以外,介绍赢得商业竞争的各方面

战略

全篇在阐述战略没有想象中复杂神秘。无非是摸清游戏规则,找到一个努力的方向,果断行动。

  • 找一个大方向,找到聪明、实用、可以获得竞争优势的办法
    • 如果大方向对头,又有一定宽度,则战略不需要经常变化
  • 把合适的人放在合适的位置
    • 为不同类型的方向安排对应特质的人
  • 不断迭代探索最佳实践
    • 学习竞争对手或是优秀同行的成功经验

找到一个可以获得优势的大方向需要一些讨论和分析,可以从下面几个角度出发:

  • 在什么场景下
    • 行业里有哪些竞争对手
    • 市场份额占有情况如何,我们的企业更擅长什么市场
    • 行业特征怎么样
      • 平民化?高附加值?
      • 长周期?短周期?
      • 在增长曲线的什么位置?
      • 决定利润率的因素是什么
    • 竞争对手的优劣势在哪里
      • 产品
      • 研发
      • 销售
      • 组织文化
    • 客户有哪些,购买方式如何
  • 最近的竞争态势
    • 竞争对手过去一年的改变市场格局的举动
    • 有什么新产品、新技术或是新的销售渠道
    • 是否进入了新的玩家
  • 我们的近况如何
    • 过去一年,我们企业对市场竞争格局的影响
    • 是否通过收购、引进新产品、挖角、引进新技术得到竞争优势
    • 是否失去某些竞争优势
  • 有哪些潜在风险
    • 对手有没有可能做出什么事情,将我们封杀出具
    • 对手有没有什么能改变游戏规则的举动
    • 公司会不会被收购
  • 有什么胜招
    • 我们能做什么——兼并、新产品、全球化
    • 如何保持用户粘性

预算

  • 不要把预算会变成辩论会或是形式化的会
  • 使用灵活的指标,不论是规划预算还是评估盈利结果,用更具建设性的方式讨论
    • 对个人和部门的奖励不是根据实际业绩与预算目标对比决定,而是通过实际业绩和此前的业绩结合竞争环境的对比决定,要考虑到现实的战略机会和困难因素
    • 这种改变的推进可能会遇到持续的阻力

有机的成长

公司内会通过孵化新产品或兼并收购来获得进一步增长。这一章先介绍新产品。对管理者来讲,有下面3个原则:

  • 做大笔投入,把最优秀、最进取、最有活力的人放在领导岗位上
    • 不要把新业务当做边缘部门,安排平凡的人
  • 大肆宣传新项目的潜力和重要性
    • 新项目报告层次至少应该提升2级,甚至到CEO的地步
  • 给予自由度,允许犯错误,让新项目自己成熟起来
    • 适当自由度会给人主人翁意识和自豪感

对新业务负责人来讲,要有创业者的心态

  • 要做好资金不足、人手不够优秀的心理准备,竭力去争取!
  • 适当渲染
  • 用自我行动争取公司的自由度

新的项目需要高水平的人才、大规模的资源投入、大规模的宣传。

企业并购

上章是增长的一种方式——新项目,这章介绍了增长的另一种方式——并购。并购有下面一些注意事项:

  • “平等合并”很难发生
    • 至少工业领域内,除了银行和咨询产业,很难发生
  • 不要过分关注经营策略的匹配而忽略了企业文化的融合
    • 不要让被收购方过于影响自己的企业文化
  • 不要在收购中让步太多
  • 整合行动节奏应该在90天内完成,不要拖泥带水
    • 公布清晰的合并程序
  • 克服“征服者综合征”,收购的目标之一是寻求更好更多的人才
    • 合并最大的战略收益之一就是让收购方从丰富的人才库来组建队伍
  • 不要付出太高收购代价
  • 作为被收购方,不能拥抱变化的人就只能离开

六西格玛

六西格玛是一种企业质量控制策略。它主要做两件事:

  • 建立体系,减衡量质量波动
  • 减少质量波动

个人发展

这一部分从个人角度出发,聊聊发展的思路。

合适的工作

寻找合适的工作需要时间、尝试和耐心。下面有一些判断工作或好或坏的信号。

    • 好信号:你喜欢那里的人,融入得很好,可以和他们很好地沟通,志趣相投
    • 坏信号:你感觉自己需要戴上面具,不会和他们交朋友
  • 机会
    • 好信号:你能学到之前没有遇到的知识,获得人生或职业的进步空间
    • 坏信号:你似乎是办公室里最聪明的人,不需要能力提升
  • 未来:从事的每种职业都是一种赌博,它可能会开拓你的发展空间或是缩小你的选择范围
    • 好信号:工作会给你能力背书;行业发展强劲或是新兴业务
    • 坏信号:该产业或公司已经过了巅峰期,不能给职业发展提供更多帮助
  • 主导权
    • 好信号:你能自己cover这个工作,同时为自己工作
    • 坏信号:你出于外在原因,或被迫选择这份工作
  • 工作内容
    • 好信号:内容令人着迷,让你感到有趣,或是热爱
    • 坏信号:只是工作而已,不过是权宜之计

同时要对薪水坦诚,尤其是职业生涯的前几年。另外:

  • 对于第一份工作的面试,如果没有明显的长处,要保持坦诚和坦白
  • 如果是当前陷入困境,被迫寻找下一份工作,要记住寻找更好的工作,最快捷的办法是在现在的岗位上干出业绩,从而不会显得是能力不足从而寻找下家
  • 被辞退后,要能坦诚面对,承认错误,然后主动地走出来

晋升

可以说晋升是绝大多数人职业生涯中努力追求的,当然首先需要有渴望晋升的欲望

  • 尽管有些晋升的机会纯粹来自于运气,但在职业生涯中,运气起到的作用比你可以控制的因素要小
  • 晋升的基础主要有两点
    • 要:要交出动人的、远超预期的业绩,同时机遇来临时,勇于扩展工作职责到预期范围外
      • eg. 超出预期的行动、新理念、新流程
    • 不要:不要麻烦老板动用政治资本帮助你(推一把就水到渠成的地步)
      • eg. 不要当刺儿头,不要表露过强的职业欲望,要获得普遍认可
  • 具体下来,用下面几点行动守则
    • 要处理好和下属的关系,像对老板一样认真
      • 也要和下属保持距离,不要跨越边界
    • 在项目上早日做出成绩,受到关注或普遍认可
      • 勇于承担大家关注的业务
    • 寻找和利用良师益友
    • 保持积极向上,不要自认为清高或华而不实
    • 不要惧怕挫折

糟糕的领导

  • 世界上总有乖僻古怪的人,有的或许就是能当上领导
  • 不能表现的像一名受害者
  • 领导一般对他们喜欢、尊重、需要的人表现并不差
  • 当价值观有问题但是绩效出色的人,公司不一定会很快开除

工作和生活平衡

本章有些屁股决定脑袋的成分,很多观点本人并不认同。

  • 老板最关心的是竞争力,他只希望你的WLB(work life balance)不要影响工作
    • 老板的第一优先级是盈利
  • 有出色业绩,才可以有余地追求WLB
    • 既然参与了工作这个“游戏”,就要服从游戏规则
  • 很多老板认为WLB是应该自己去解决的问题,不应该交给公司
    • 工作和生活总需要平衡和取舍,自己需要承担后果的

其他

其他的一些零星问题

  • 竞争力的三要素
    • 成本、质量、服务
  • 考虑公司文化多元化

--END--

0%