0%

纸上得来终觉浅,绝知此事要躬行。

一定要做计划

做计划时,任务的粒度一定要细,分解的越细,越能及早的发现实际和计划之间的偏差,不至于到最后不可挽回。

任务的结果一定要明确、可量化、易检查,模糊不清的结果是无法判断是否完成了的。

以软件中的模块开发为例,可以分解为XXX模块开发,也可以分解成XXX模块接口定义和XXX模式接口实现。在实际执行中,推荐采用后者。

一个经验教训是,模块的对外接口、系统的对外接口(接口包括但不限于API、通讯规范、交互模式)都需要先评审,评审通过后再继续后续开发。

一定要监控计划的落实情况

实际情况和计划一定会有偏差,有偏差是正常的,没有偏差才是不正常的,关键在于是否及时的发现了偏差并采取了应对措施。所以一定要监控计划的落实情况

要形成适合自己的工作流程

管理书上讲的流程、工具当然是有用的,但应该根据自己的实际情况裁剪,定制属于自己的工作流程,并经常评估是否还满足当下的实际情况。

事情的可观测性/可量化性

项目的进度、执行的结果都应该是可观测的、可量化的,否则很容易成为一锅粥。

做事情的原则

  1. 做事情、评估事情时,不能仅限于把眼前做好,还应该关注它对我未来有什么用
  2. 在做事情之前,应该想清楚,它应该是什么样子,现有的资源我能做成什么样子,以什么途径向最终的样子去逼近,也就是所谓的以终为始

在排查动态库符号查找失败、符号覆盖时特别有用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 LD_DEBUG=help ./program1
Valid options for the LD_DEBUG environment variable are:

libs display library search paths
reloc display relocation processing
files display progress for input file
symbols display symbol table processing
bindings display information about symbol binding
versions display version dependencies
scopes display scope information
all all previous options combined
statistics display relocation statistics
unused determined unused DSOs
help display this help message and exit

To direct the debugging output into a file instead of standard output
a filename can be specified using the LD_DEBUG_OUTPUT environment variable.

从头到尾刷了下云风的博客,将和C、软件设计相关的文章汇总在了该页面,有时候,通过查看文章下面的评论更能理解文章在说什么

关于 getter 和 setter
好的设计
C 语言对模块化支持的欠缺
浅谈 C 语言中模块化设计的范式
给你的模块设防
我所偏爱的 C 语言面向对象编程范式
关于分工合作
libuv 初窥
Ring Buffer 的应用
一起 select 引起的崩溃
断点单步跟踪是一种低效的调试方法
程序员应该怎样提高自己
一个 C 接口设计的问题

linux socket API connect函数,在socket是堵塞模式下,该API是不允许设置超时时间的,一个经常的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include	"unp.h"

int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
int flags, n, error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;

flags = Fcntl(sockfd, F_GETFL, 0);
Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

error = 0;
if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
if (errno != EINPROGRESS)
return(-1);

/* Do whatever we want while the connect is taking place. */

if (n == 0)
goto done; /* connect completed immediately */

FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;

if ( (n = Select(sockfd+1, &rset, &wset, NULL,
nsec ? &tval : NULL)) == 0) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return(-1);
}

if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return(-1); /* Solaris pending error */
} else
err_quit("select error: sockfd not set");

done:
Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */

if (error) {
close(sockfd); /* just in case */
errno = error;
return(-1);
}
return(0);
}

这是Unix-Network-Programming书上给的一个示例程序,但要注意,实现过程中采用了select函数,所以sockfd不能超过1024,否则会出问题

因为只离线安装过openssh-server,所以以该软件包的安装为例,想必其它软件包操作方式类似

  1. 下载openssh-server包

    1
    sudo apt-get download openssh-server
  2. 下载openssh-server依赖包

    1
    sudo apt-get build-dep --download-only -o dir::cache=PATHFORDEPS openssh-server

    PATHFORDEPS 替换为保存依赖包的目录

  3. 下载额外的依赖包

    1
    sudo apt-get download openssh-sftp-server openssh-client
  4. 安装依赖包
    注意,通过find命令将所有的依赖包和主包放在同一个路径下面

    1
    sudo dpkg -i *.deb