读《华为管理法》

这是一本分析华为公司的书,主要参考《华公司基本法》(于1998年推出,可能是我国第一个企业级基本法)。

华为的创始人任正非先生,自创立华为以来,一直在研究如何让一家公司基业长青。他认为,华为公司什么都不需要留下,很多东西也很难留下,只要将企业文化、管理体系留下来,公司一定能长久地走下去。

以下是作者分析华为成功的一些要素。

公司在战略上需要聚焦,才能在这个领域里有所突破。任何时代,都有很多机会,但不可机会主义。坚持主航道,不为蝇头小利而偏离前进的方向。对个人也是一样,精力是有限的,在别的事情上花费太多时间,必然减少在关键任务上的时间。

企业的发展既需要一大批人务实,人事具体的工作,也需要有人务虚,制定企业发展的战略。只要少数高层从事务虚工作即可,基层都要务实。

要民主地对待团队,充分发挥各路英雄的作用。一个人的力量总是有限,需要团队共同的智慧。如何将团队中各人的力量发挥出来,是管理者的关键任务。

坚持以结果为导向考核员工,对员工的评价,看贡献,而不是看加班加点。能很快把活干完,质量还很高,贡献也很大,可以给他换一个岗位,多做一些事,同时考虑提拔一下,让其发挥更大的作用。

末位淘汰制度,可以打破员工的安逸感。

员工未达到考核标准,也有管理者的责任。员工的成绩,就是管理者的成绩。

理论要与实践相结合,学习新理论后,需要实践,然后总结,才能提高能力。

员工之间的相互培训,可以提高团队整体水平,降低培训成本。员工入职前的培训也很重要,在培训中,可以由老员工一对一带新员工,并且对新员工的培训结果负责。条件允许的情况下,增加一些专业的职业培训。

作为领导者,要在茫茫的黑暗中,发出生命的微光,带领着队伍走向胜利。

作为团队领导,更重要的是把自己的部下源源不断地培养成英雄,而不是自己去当个人英雄。所以,领导都要淡化个人成就感,注重组织目标的成就感。

管理者要培养能超越自己的接班人。

在企业管理中,管理者一项极其重要的修养,是宽容待人。企业管理者唯有宽容才能够把员工团结在管理者周围。员工犯了错误,要耐心处理,切忌暴躁。

在企业成功之后,仍然要保质艰苦奋斗,主要是思想上的艰苦奋斗,时刻保质危机感。

现代企业的竞争已不是单个企业之间的竞争,而是供应链的竞争。整个供应链上的企业都有钱赚,自己才能走得长远。

华为不上市,是为了更好地服务客户。资本的本性是追求利润最大化,甚至企图在短期获得较大的投资收益,这会影响企业的长远健康发展。

解决 TextWrangler 中文乱码的问题

在苹果电脑上打开 Windows 下创建的 txt 文件,其默认的文本编辑器不好用。根据网友的推荐,选择使用 TextWrangler 打开 txt 文件。但是遇到了 2 个问题:

每次都要通过右键 -> 打开方式,选择 TextWrangler 来使用

这特别不方便。如何让系统默认使用 TextWrangler 打开 txt 文件呢?步骤如下:

  1. 右键点击要打开的 txt 文件,点击显示简介;
  2. 找到“打开方式”,展开该部分内容,点击选择要设置的默认软件(TextWrangler);
  3. 最后点击“全部更改”,确定即可。

这样,点击所有的 txt 文件,都会以刚才设置的 TextWrangler 打开。

打开 Windows 系统下创建的 txt 文件,中文会显示为乱码

每次都要通过 File -> Reopen Using Encoding 选择 Chinese(GBK) 来解决。

那么,能否让 TextWrangler 自动识别中文呢?经过多次倒腾该软件,终于找到解决办法:

  1. 点击菜单的第一项 TextWrangler -> Preferences -> Text Encodings
  2. 找到 If a file's encoding can't be gussed, try 这部分设置,点击下面的 + - 按钮,将框内设置为 Chinese(GBK)

TextWrangler_setting.png

这样,下次打开含有中文的 txt 文件,就可以正常显示了。

PHP 命名空间(namespace)详解

PHP 的命名空间(namespace)概念是从 5.3.0 开始引入的。在其它程序语言中,命名空间相当于文件夹,是用来对类文件进行分组的。许多 PHP 框架已经全面使用命名空间特性。

命名空间的引入,主要是为了解决类、函数、常量与 PHP 内部或者第三方库之间的名称冲突。

基础

语法主要是声明与使用。

声明:

// file: foo.php
namespace foo;
class Bar {}

使用:

// file: test.php
include 'foo.php';
$bar = new \foo\Bar();
// 使用别名
use foo as first;
$bar2 = new first\Bar();

声明必须放在其它代码之前,declare 关键字除外。

注意,在使用别名时,前面不能加反斜杠(因为反斜杠表示全局命名空间,而别名不是实际存在的命名空间)。但是引入进来的命名空间 foo,在使用时,必须加上正确的限定,确保命名空间的正确解析。在设置了别名后,原名称依然可用。

如果当前代码没有声明命名空间,则为全局命名空间(或者称为根空间)。

如果当前代码声明了命名空间,那么使用不带命名空间的类,会默认以当前命名空间作为限定。如果当前命名空间不存在该类,则会报错。

要使用引用文件中的类,且被引用的文件使用了命名空间,必须带上命名空间前缀。否则,使用的是当前命名空间下的类。

命名空间的名称,可以是多层级的(可称之为子命名空间),如 namespace foo\bar,使用时可以把它当作一个层级一样处理。

关键字 namespace 也可以出现在命名空间的“路径”中,放在“路径”的开头,指当前的命名空间,不管当前文件有没有声明命名空间。也就是说,在不是反斜杠开头的名称前加 namespace\ 总是正确的。

由于命名空间可能层次很多,书写麻烦,可以使用 use 语句设置别名,不加 as 则表示使用命名空间最后一节作为别名。

use My\Full\Classname;
use My\Full\Classname as C;

上一条语句与 use MyFullClassname as Classname 效果一样。下一条语句,是为了进一步简化别名。

注意,use 语句中的命名空间不需要以反斜杠开头,但在开头加上反斜杠也没有问题。如果 as 的别名与当前命名空间下类名相同(当然该同名类一定不会在当前文件中),将优先使用 as 别名对应的类。

导入函数(使用 function 关键字):

// PHP 5.6+
use function My\Full\functionName as func;

导入常量(使用 const 关键字):

// PHP 5.6+
use const My\Full\CONSTANT;

以上导入函数和常量的名称,如果与当前命名空间的名称冲突,可以用 as 取一个别名。

为了简化操作,可以将多个 use 语句写到一行:

use My\Full\Classname as Another, My\Full\NSname;

与其它语言不一样的地方是,同一个命名空间的代码可以定义在不同的文件中。

使用常量 __NAMESPACE__ 可以获得当前代码所在的命名空间。

进阶

一个文件多个命名空间

PHP 也允许在一个文件声明多个命名空间。

<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

它表示,文件中的代码按块划分到 2 个命名空间。一般像这样使用,主要用于将多个文件合并到一个文件:

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}

上面代码中,第三个 namespace 后没有命名空间名称,这表示是全局代码。混合在一个文件中的代码只能这样组织,命名空间的大括号外不能有任何 PHP 代码(declare 语句除外)。

命名空间的层次关系

名词定义:

  • 非限定名称(Unqualified name):名称中不包含命名空间分隔符(反斜杠)的标识符,例如 Bar
  • 限定名称(Qualified name):名称中含有命名空间分隔符(反斜杠)的标识符,例如 fooBar
  • 完全限定名称(Fully qualified name):名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,例如 fooBar。 namespaceBar 也是一个完全限定名称。

前面两种名称,没有以反斜杠开头,是相当于当前命名空间的名称。可以将 PHP 命名空间与文件系统作一个简单的类比。在文件系统中访问一个文件有三种方式:

  1. 相对文件名形式如foo.txt。它会被解析为 currentdirectory/foo.txt,其中 currentdirectory 表示当前目录。因此如果当前目录是 /home/foo,则该文件名被解析为/home/foo/foo.txt。
  2. 相对路径名形式如subdirectory/foo.txt。它会被解析为 currentdirectory/subdirectory/foo.txt。
  3. 绝对路径名形式如/main/foo.txt。它会被解析为/main/foo.txt。

PHP 命名空间使用同样的原理。例如,类名可以通过三种方式引用:

  1. 非限定名称,即不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 注意:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。(注意只是函数和常量,不包括类。类的访问行为与此不同,见下文。)
  2. 限定名称,或包含前缀的名称,例如 $a = new subnamespacefoo(); 或 subnamespacefoo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespacesubnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespacefoo。
  3. 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new currentnamespacefoo(); 或 currentnamespacefoo::staticmethod();。在这种情况下,foo 总是被解析为代码中的字面名(literal name)currentnamespacefoo。

全局命名空间

反斜杠()表示全局命名空间,使用 PHP 内部函数,始终可以使用反斜杠作为前缀。

访问任意全局类、函数或常量,都可以使用完全限定名称,例如 strlen() 或 Exception 或 INI_ALL。尤其是当命名空间内,存在与全局类、函数、常量相同的名称时,若想使用全局类、函数、常量,则必须加上反斜杠,否则使用的是当前命名空间下的类、函数、常量。

namespace A\B\C;

/* 这个函数是 A\B\C\fopen */
function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
}

在声明命名空间的代码中访问全局类(必须使用反斜杠)

namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是全局类 Exception 的一个对象

$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类

但是,对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会使用全局空间中的函数或常量。

注:本文部分内容转载自官方文档。

参考文档:
PHP 命名空间

推荐一款 MySQL 定时备份脚本

数据库的备份是非常重要的。我在使用数据库时,写了一个 Shell 脚本,利用 Linux 的 crond 实现每天自动备份数据库,保留近期的备份数据(删除更旧的数据)。

脚本其实是用 mysqldump 命令导出数据到指定目录,对于中小型数据量已经够用。但当数据量超过 1G 时,导出的时间明显加长,而且恢复数据也会很费时间。还有一个缺点是,备份期间,会锁表,其它用户无法写数据库。因此建议在用户使用低峰期备份数据库。

对于大数据量,建议使用开源软件 XtraBackup 进行备份。后面我也会将这个备份程序集成到备份脚本中。

要使用的话,请克隆源代码,参考说明文件即可。

如何理解 SaaS 和 PaaS

近一年来,当有人问我做什么工作时,我回答说,我就职于一家 SaaS 软件公司。别人又问 SaaS 是什么?这不是一句话能说清楚的。你说就是“软件即服务”,人家还是云里雾里。

其实我们还经常听到 PaaS 这个词,当然还有 IaaS。下面是这三个词的英文及中文直译:

  • IaaS, Infrastructure as a Service, 基础设施即服务
  • PaaS, Platform as a Service, 平台即服务
  • SaaS, Software as a Service, 软件即服务

下面以做一个电商网站为例。十年前,需要做的事情有:购买服务器(如购买 Dell 机器托管到电信机房)、安装操作系统(一般是 Linux)、安装 Web 软件(如 Apache, MySQL)、编写网页程序(如用 PHP 程序)。

现在:

IaaS

不用购买物理机,一般也不用安装操作系统。IaaS 服务商已经提供好了,按需选择。但后面的事情还是要做。

因为过于基础,要么落伍了,要么转型到 PaaS 了。

PaaS

除了不用购买物理机和安装操作系统外,也不用安装 Web 软件,直接使用服务商提供的软件服务。如阿里云,无需安装 MySQL,购买其服务(云数据库RDS),使用即可。相当于为公司省去了 DBA 这个岗位。还可以使用其它软件服务,如缓存、搜索等。这些基础软件都由 PaaS 服务商提供,你专注于业务程序开发。

主要是面向软件开发者。市面上的云计算平台(云服务)可称之为 PaaS 服务商,提供硬件、操作系统、基础软件服务,帮助开发者免运维、快速地开发软件。其实它和 IaaS 有部分服务是重合的,二者的界限没那么明显。

SaaS

连程序都不用开发了,SaaS 服务商直接提供可以使用的软件,一般是网页形式,现在也配有移动客户端。那么上面的这个需求,可以用“有赞”实现。购买其服务套餐,设置店铺标题、录入商品信息,就可以卖货了。

主要是面向软件消费者。一般是指企业管理软件,如 CRM, HRM, SCM 等,其实现在用户使用的所有软件,都可称为 SaaS 服务。

可以看到三者是一个递进关系的层次结构,开发者要做的事情越来越少。如下图示:
iaas-paas-saas.jpg