0%

文章摘自微信公众号:十三先生手记

人们总是误以为”方向不对,努力白费“

所以到底什么方向是努力的正确方向,是对事情方向性的选择吗?
看起来是这样的,其实不然,在事情没有出现结果之前,谁能确定方向对不对?
于是乎,在很长一段时间里,你在方向的选择上纠结,大量耗费了精力;久而久之,方向选择对你的意义就逐步降低;久而久之,你在没有了方向的努力中不断的迷茫,努力所收获到的就多半不如意;久而久之,你便自然逐步丧失了努力的动力。

所以其中蕴含真正的智慧是什么呢?
此刻,十三先生要你深深的明白:对于你真正想要成就的方向而言,基于外在目标而牵引你的行动方向就是你的迷障,基于你内心真正愿意去做的方向才是真正利于你达成整体目标的方向。若是你在每次做选择之际,你都按你内心真正未权衡的意愿立刻去着手行动,并在行动的过程中,实事求是的不断优化解决遇到的问题,而不是在事前先拿你预设的可能遇到的问题去和你的资源做权衡匹配,在来做方向选择的决定,假以时日,必定你会不断收获到你真正想要收获到的利益。

个人感悟

与其纠结于方向正确,不如尽快行动起来,尽快在行动中感受自我。那些未经反复驱动,内心自发想要完成的事情就是你人生的正确方向了。

头文件通常包含的内容

  • 函数原型
  • 使用了#define或const定义的符号常量
  • 结构声明
  • 类声明
  • 模板声明
  • 内联函数
    用#include “”率先在当前工作目录或者源代码目录下找
    用#include <>率先在标准头的目录下找

同一个头文件只包含一次

1
2
3
4
#ifndef INCLUDE_H_
#define INCLUDE_H_
...
#endif

多个库的链接

需要确保对象文件或库都是由同一个编译器生成的,若不同的编译器,会为同一个函数生成不同的修饰名称。若有源代码建议用自己的编译器全部重新编译,以消除链接错误。

存储数据的三种方案

  • 自动存储持续性:函数中声明的变量以及函数参数,会在执行中自动创建,执行完自动释放
  • 静态存储持续性:使用static关键字的变量,在整个程序运行过程均存在
  • 动态存储持续性:用new分配的内存,一直存在直到delete

编译器把自动变量用堆栈的形式管理

register的变量放在寄存器,依然没有链接性

静态存储提供三种链接性

  • 外部链接性:全局(外部链接性)变量(main函数外)
  • 内部链接性:static的全局变量
  • 无链接性: 内部的static变量
    静态变量持续整个程序执行期间,编译器将分配固定的内存块来管理。默认情况下,静态数组以及结构的成员都设置为0。

外部链接性使用

1
2
3
4
5
6
7
8
9
10
11
12
// file1
int status = 100;
#include "file2.hpp"
print();

// file2
extern int status;
void print()
{
cout << status;
}

如果file2中,用status int status或者 extern int status=20;都会报重新定义的错误。

应使用外部变量在多文件程序的不同部分共享数据

内部链接性的静态变量用于多个函数之间共享数据(名称空间提供了新的共享数据方法,static的内部链接性逐步淘汰)

存储说明符:auto, register, static, extern, mutable

auto为自动变量;register为寄存器存储;static在整个cpp文件的声明具有函数间的链接性;extern是多文件的外部链接性;mutable使const临时失效;
volatile指程序代码没有对内存单元修改,其值也可能发生变化。即每次使用该变量都应其查找,别用缓存。

另外

1
const int fingers = 10; //same as static const int fingers;

const使全局变量变成了内部链接性。

但是在另外的文件用 extern const int fingers;又可以强行变成外部链接性而可用。

关于函数的链接性

由于C++不允许函数中定义另外的函数,所以所有函数都为静态存储持续性。但依然可以用extern来使函数为另一个文件使用。使用该函数的每个文件应包含函数原型(方便了解接口的描述,内联函数可以无需接口描述)

语言链接性

由于C和C++编译器对函数翻译不一致,在调用C外部链接函数时,应该标注extern “C”

1
2
e.g.
extern "C" void spiff(int);

布局new占位符

1
2
3
4
const int BUF = 512;
char buffer[BUF];
double *pd1 = new double[BUF];
double *pd2 = new (buffer)double[BUF];

上述两个指针,pd2为交由程序员自身管理的动态内存;且pd2在delete管辖区域之外。

命名空间及前途

  • 命名空间具有外部链接性
  • 使用在已命名的名称空间中声明的变量,而不是使用外部全局变量
  • 使用在已命名的名称空间中声明的变量,而不是使用静态全局变量
  • 如果开发函数库或者类库,将其放入一个名称空间中。如当前C++提倡标准库的都放入std空间中
  • 不要在头文件使用using,这样会掩盖了可用的名称;另外包含头的顺序会影响程序的行为;若坚持则应在所有的#include后用
  • 导入名称时,首选用作用域解析或using声明
  • 对于using声明,首选将作用域于局部,而非全局

命名空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中

using namespace std;就是using编译指令,使整个名称空间可用。

文章摘自微信公众号:十三先生手记

小时候,我就一直渴望幸福,一直渴望坚强;
小时候,我就一直渴望正直,一直渴望善良;
小时候,为就一直渴望快乐,一直渴望成长;
现在,我几乎丢失了我的信心,我几乎丢失了我的梦想!
我知道,我不能再这样消极的逃避。
我知道,我不能再这样平庸的彷徨。
我知道,我要全力迸发我的热情;我要勇敢的收复我的希望。
我知道,我要真诚的对待身边每一个人,这样,我才能被每一个人真诚的对待;
我知道,我要用心的对待每天的时光,这样,我才能收获每天的力量;
我知道,我要帮助身边每一个人达成心愿,这样,大家才能帮助我实现梦想。
从今天起,我要打败我的懒惰,重拾我的阳光;
从今天起,我要改变我的粗俗,提升我的修养;
从今天起,我要挑战我的懦弱,找回我的坚强;

我是为爱这个世界而来
我要让世界因我的爱而更加美丽,
我要让世界因我的爱而更加安康,
我要让世界因我的爱而更加真诚,
我要让世界因我的爱而更加和畅。

do…while… 至少会执行一次的循环逻辑

哨兵(sentinel)字符: 一直读取,直到’他‘为止

检查文件是否正确打开很关键

用string读ifstream数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <fstream>
#include <string>
int main()
{
using namespace std;
ifstream inFile;
inFile.open(filename);
if(!inFile.is_open())
{
cout <<"Failed Open";
exit(EXIT_FAILURE);
}
// 逐行读放在string
string str;
getline(inFile, str);
//stoi, stof, stod
}

关于函数,真正的乐趣在于编写自己的函数,函数库

指向const的指针以及const指针

递归使用

1
2
3
4
5
6
7
void recurs(arg)
{
stat1
if(test)
recurs(arg)
stat2
}

先执行stat1,打开满足条件,打开新的递归;直到新的递归不满足条件,逐步执行stat2并关闭当前函数;直到所有打开的函数都关闭了。

函数指针

用函数指针将第一函数找到第二函数,而非直接调用;虽然笨拙,但好处是可以在不同时间传递不同的函数地址;
语法:double (*pf)(int);

应尽量使用const

1.使用const可以避免无意中修改数据的失误
2.使用const使函数能够处理const和非const实参,否则将不能处理const实参
3.使用const引用使函数能够正确生成并使用临时变量

引用非常适合用于结构和类

何时使用引用参数:1.能够修改调用函数中的数据对象 2.通过传递引用而非拷贝提高程序运行速度

语法糖:函数默认参数从右往左

函数多态:重载函数

不应滥用,适用于不同参数类型输入,完成基本一致功能的多个函数使用,const与非const也不一样

函数多态:模板编程

1
2
3
4
5
6
7
8
9
template <typename T>  // typename -> class is ok
void Swap(T &a, T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}

编译器如何匹配最佳函数是一个复杂而完备的过程,大致规则如下:
1.完全匹配,但常规函数优于模板
2.提升转换(char/shorts提升至int, float提升至double)
3.标准转换(int 转换char, long 转换double)
4.用户定义的转换,如类声明

C-style字符串

结尾带’\0’,这对于很多处理字符串的函数很关键。#include 包含大量C语言字串的操作函数如strlen, strcpy, strcat…

strlen():只计算数组或者指针中的字符个数,不带结尾

cin.getline(name,20):读取整行的字串到name,最多20个
cin.get():类似,但下一次调用开头会带有换行(换行缓存到下次get),顺便检查了上一次输入的正确程度。

针对string类的getline(cin, string); 与cin混合使用时,在cin>>完成后,getline前需要通过getline(cin,”\n”)清除缓存,否则不进入getline输入。

1
2
3
// 清除缓存
string str="\n";
getline(cin,str);

string类

1
2
#include <string>
std::string

更方便,也更安全。像vector一样管理char.

struct和union

union只能同时存储一种类型,其他类型的会lost

new和delete

  • 不要delete释放不是new的内存
  • 不要delete同一块内存两次
  • new[]数组应当用delete []释放
  • 若用new[]为单一实体分配内存,应使用delete(不带方括号)释放
  • 对空指针delete是安全的

cin与cin.getline区别

cin.getline(addr,80) 与cin>>addr
getline:读整行直到‘回车’
cin:首先跳过‘空格’,读取字串,再次遇‘空格’停止;即跳过前面的空格,读取单个单词。

1
2
3
cin>>ch;
cin.get(ch);
ch=cin.get();

上面区别主要是cin>>ch直接跳过空格换行以及制表符

string格式化输出4位数字,前面补0,多用于文件名操作

1
2
3
int num_zero = 4;
string num = to_string(int_val);
string new_num = string(num_zero-num.length(),'0') + num;

注意int_val长度小于num_zero。

c++基本数据类型主要有bool, char, int, float, double。具体如下:

basic data structure
basic data structure2

另外,C++生成代码的过程是:1.程序员编写源代码 2.编译器正确翻译C++为目标代码 3.链接器将环境启动的代码以及引入库的代码与目标代码正确链接 4.最后才输出机器认识的可执行代码
code procedure

整型提升(integral promotion): 计算表达式时,bool, char, unsigned char, signed char short会转换为int,即int为计算机最自然的类型,也是运算速度可能最快的。较小与较大运算也可能提升。

一部工业革命后的近代科技发展史

第一次阅读这本书大概是在大学的时期,当时应该还是第一第二版的样子。可惜当时认知有限或者是兴趣使然,确实是没有坚持读下来。作为一本信息科技人的导论书籍,吴军老师主要是从创始人及公司基因,资本加速以及调整创新等多个维度阐释每一个时代的技术浪潮。也让我重新认识硅谷,重新认识所有信息产业耳熟能详的近代技术及工业制品。有点后悔当初年少没有认认真真开启好这一本导论,以致于没有一个非常完备的大局观去规划个人职业生涯以及技术路线。弯弯曲曲之下,也就不难预见自己人生所能触及的高度了。

重新认识知名或者耳闻的科技公司发展

读完整篇最大的收获一方面是吴军老师分析浪潮与技术史的方法论与发展观,另外就是让我重新其认识那些早有耳闻的科技大公司以及了解他们所处时代的科技浪潮与技术产品。按照章节来列举的话:

  • chap 1 北美最大的通讯服务商AT&T及其贝尔实验室,对应国内就是国家垄断的电信移动联通三巨头。信息社会中,通讯业至关重要,从通讯硬件供应商以及软件算法的比如思科,华为;到对接用户的服务供应商,只要能分享整个通讯产业链的某一部分就存在巨大的利润。而且通讯的技术和协议也在不断更迭,从有线->无线->光纤->WIFI6,从2G到5G等等。
  • chap 2 最早真正研制出计算机的IBM以及其从卖服务器PC到后来成为最大的服务提供商。说实话,IBM的名字在大学时期是如雷贯耳但我却从来不知道他是做什么的。而且至今,我对这家公司的印象和认知可以说都是比较模糊的,但我知道他的TO B服务应该很强。
  • chap 3 “八叛徒”引出了硅谷不断开拓创新的精神,从一个核心技术到多个子公司分门立派相互竞争促进,大大加快了IC电路的发展,让我们真正迎来经久不衰的半导体时代。这个有点像一套绝世武功,虽然细节粗糙,但核心理论和精神质变于现有的功法。于是所学的弟子们都自立门派,却又各负盛名。最大的点是芯片技术乍看只是两个核心专利的技术,却影响千千万万,甚至于卡住了我们科技强国的脖子。再次,技术之间的差异如同人之间的差异。对于社会,最有价值的工作可能是20%的人所完成的;对于个人,最有价值的工作可能是20%的时间和精力里做出来的。那么,如何提升这一个比例呢?比如对于自己,如何让自己的时间和精力专注在最有价值和意义的事情上。如何让自己成为那20%最有价值的人,价值与流量是共通的。为着最大的社会群体服务,为着最广阔的行业作贡献。更细粒的维度划分就是从用户群体以及用户时间,从社会进步及人类进步去思考。(我承认,有点发散了,就当与自己对话了~)
  • chap 4 详尽介绍苹果公司的起落,尤记10年前,乔布斯是无数IT从业者最重要的偶像物,如今又有新的浪潮涌起,比如马斯克。相信粉老乔的,都会读那本经典的自传,就不难认识到苹果了。一直以来,苹果在致力创新智能硬件与大多数人生活上的交互方式。从最早的UI系统,到后来的IPOD,IPHONE等。虽然不像安卓那样开源,但苹果的工程师依然非常的顶。极大的推进产品的质量以及竞争力,他们对产品的整合能力也非常出众,致力于把每一款推向市场的产品做到极致完美。以至于非常长的时间里,直到今天,我认为苹果公司推出的是市面上比较完美的智能设备,当然价格也很丰满。苹果的利润率是业界闻名的,除了产业链整合以及大品牌效应能从渠道方压缩成本,更重要的是在长时期里核心技术不断研发和积累的成果。
  • chap 5 引出第一个方法论,信息产业的三大定律:1.摩尔定律,集成电路的集成度每18个月翻一翻。因此半导体智能产品的性能也翻番,说明一个高速发展的IT行业是呈现指数增长 2.win-tel定律,基于摩尔定律,硬件进步了,软件也会相应占用更多的资源,以此发挥硬件的能力,倒逼硬件行业完成摩尔增长 3.反摩尔定律,对于处在摩尔定律行业的公司,如果不进步达到指数,则在退步。如果只维持去年的水平,18月后就会下降剩一半。
  • chap 6 Intel的芯片,全球通用且难有敌手。因为PC端的芯片研发成本摆在那儿,1985对32bit的80386研发投入就超过3亿美元。而且从芯片制程特殊性而言,集成度更高性能和功耗都提升,体积下降。大部分消费者难以退回旧一代的芯片,所以赢者通吃,落后者剩菜残羹。今时今日,除了MAC电脑,绝大部分的PC都采用intel芯片,而且服务器端也有见长。但是浪潮之中PC市场相对饱和,移动端崛起了10多年,更多的芯片战场转移到嵌入式去了。往后的就是终端芯片为主的变革,比如ISP,算法芯,AI芯等。
  • chap 7 关于微软以及windows。真正意义第一个垄断性的超级公司就是微软了,因为其卖软件的特性,利润率极高。在PC时代无人匹敌,依赖windows系统,其绑定的PC软件也得到天然的优势。而后移动互联网浪潮来临,微软虽然没有攀上浪尖,却也从游戏方面入手取得不俗的成绩。由此奠定了大公司希望涉猎互联网的全领域利润,比如搜索,社交,移动支付,手机等等。但始终只留下其最擅长的产品。拥有再多第二第三列的产品并不足以让一家企业成为真正帝国性一样富有影响力的机构。另一方面也告诫我们,需要专注,成为单一方向最拔萃的人。
  • chap 8 Oracle,一家以数据库闻名的企业。大概是大二还是大三的时候,首次听到这家公司的名字,但依然不得其意。大概跟IBM类似较多开展企业级相关的服务和技术支持。
  • chap 9 思科通信巨头,主营交换机路由器等互联网基础设施。早期是互联网用于大学公司等,主要方便学术与办公交流。由于各个子网的网络协议不一,思科早期推出多协议路由终端成为子网间互联的关键。同样互联网的浪潮帮助思科乘风破浪。另外当时红杉资本热衷投资给年轻的穷人,因为越是贫穷越有成功的欲望和拼搏精神。西方的思科,东方的华为。华为起步只比思科晚4年,同样掌握当时世界最前沿的通信技术,通过大批雇用IBM顾问从而实现早期国际化的管理水平。至今华为找到手机移动的增长点,焕发最强民企的生命力。2020年统计,华为的科研投入遥遥领先于第二名的腾讯一倍有余,狼性文化下也涌现超级年薪的PHD。
  • chap 10 YAHOO互联网入口,世界第一个黄页。除了整理了当时杂乱的互联网资信,吴军老师认为YAHOO制定了互联网行业重要的规则:开放,免费,基于流量的盈利模式。我认为这与当今的开源思想很有共同点,区别在于开源目前变现能力还不够。为此,我特意知乎了开源目前的盈利模式,主要有以下七个:1.多种产品线,开源版推广,专业版收费; 2.提供技术文档,培训以及二次开发作为收入(不是长久之计); 3.应用服务托管,相当于云部署; 4.软硬一体化,开放软件,销售硬件 5.开源作为附属品 6.提升品牌和服务(大公司) 7.市场等其他 回到雅虎,当时手工密集式整理互联网信息,使之成为大部分人连接互联网的入口,加之互联网的快速发展使其价值和流量不断提升,也找到广告盈利的模式。当然资信发达引入的问题是对搜索引擎的迫切需求,以至于后来GOOGLE的崛起。当时浪潮之大,以至于当时只要有流量就有钱和投资,大量tricks如何提升网站流量的热度,狂热之下,互联网泡沫来临。网站大洗牌,小公司以及虚胖的大公司都一泻千里,被浪潮拍打在沙滩上。度过寒冬的以及寒冬后的企业,迎来了新的社会资源和人才,缺少老旧对手也能快速崛起。
  • chap 11 惠普,一家如今印象只有打印机和PC产品的企业。殊不知一直以来是硅谷神话的代表,也是最早进驻斯坦福工业园的企业,开启了新时代校企合作的高效模式,高校培养顶尖人才,企业吸收并转化成遍布全球的产品。上世纪的惠普主营三大板块包括科学仪器,医疗器材以及计算机和外设,而后经营不合理导致只拆分剩计算机以及外设。
  • chap 12 没落贵族-摩托罗拉,最早做通讯设备的公司,包括军用民用无线电,大哥大到2G手机。然而固有利润高的市场抑制了内部4G的推广,可见连内部都产生抑制新技术和新产品的现象,资本市场的竞争是十分激烈的,尽管存在反垄断法,但公司一旦占据行业的龙头位置,后来者就再难以从同样的赛道超越,除非是科技或者产品以质级的飞跃。