精华内容
下载资源
问答
  • 学员提问: 今年刚刚21岁,找了一份运维的工作,希望...所谓的定制化岗位就是这个岗位所用到的技能和方法,只适合于当前这家公司,当你有一天离职,你会发现别的公司都没有这个软件和工具, 等同于你离职即失业。 .

    学员提问: 今年刚刚21岁,找了一份运维的工作,希望运维前辈给年轻的后辈一些建议?

    答: 首先纠正一点:后辈就后辈吧,别老说自己是年轻的后辈,年轻,我们八零后也不老嘛。

    下面是正文:

    运维行业,入门容易,精通难;

    你需要提前知道的是:

    1. 企业的业务不同,运维的工具和中间件也会各不相同,技术的侧重点会不一样,但要尽量避免定制化岗位。
      什么是定制化岗位?

      所谓的定制化岗位就是这个岗位所用到的技能和方法,只适合于当前这家公司,当你有一天离职,你会发现别的公司都没有用这个软件和工具, 等同于你离职即失业。

    2. 在你的薪资达不到14K左右的时候,请尽快掌握运维的通用专业知识,尽可能的适应多家公司。

      所谓的通用知识指的是:apache,nginx,Tomcat,zabbix,prometheus, docker,ansible等这些常见的技术。

      或者你在boss上搜运维岗位,能够看到的高频知识点。

    3. 当你已经拿到14K的薪资后,一定要在某一个方向的上深入钻研,比如nginx,zabbix,MySQL等,随便选一个方向去研究;

    4. 当你在一个方向足够领先后,你才有必要去研究精通其他领域,但不管你想精通哪个领域,请先确保你的基础知识足够扎实。

      千万不要出现,精通zabbix, 但连查找个端口号是否被占用都得需要百度的情况,这是很多人容易犯得误区。

      很多有多年工作经验的人去面试看到笔试题扭头就走,不是说笔试丢人,而是面试者虽然有多年工作经验,但基础知识不扎实。

      请注意:这是个很普遍的现象,你只要避免就超过了80%的人;

    5. 当你的薪资达到20K的时候,你就可以考虑学一门编程语言了,比如java。

      Python并不是运维开发的唯一选择, 学习编程的目的是让自己养成一种思维习惯,能够从编程的角度了解自己运维的产品。

      有了编程能力后,你对运维行业理解就多了一个新视角,会突然明白以前有些东西的确是在做无用功。

    6. 21岁能入行,有可能你的学历是专科,尽自己所能进修学历,一直到研究生学历为止,越早越好。

    最后分享五点:

    • 网络基础是很多运维的弱势,如果你也是,尽快补上;
    • 桌面运维,windows运维没有持续研究的必要,尽快转Linux运维;
    • 运维行业知识繁杂,但不要养成囤积知识的习惯,放在百度云盘里的知识不叫知识。
    • 尽快找女朋友,年龄越大,你的工作越忙,女朋友越不好找。
    • 如果不打算在一线城市,一定要提前做好规划,因为你的老家可能没有运维岗或者即使有,但工作职责和一线城市不同且薪资低。

    最后的最后:
    在你拿到30K之前,不要迷信风口,不要追热门技术,因为但凡是风口,你都不会是提前知道的那一批人。

    展开全文
  • 但对于一部分同学来说,没有众观全局就会误以为入门就需要学习庞大的知识,学着学着开始看不懂,由于心理作怪,感觉内容巨多,之后就真的一直看不懂了。 但C语言的基础内容真的多吗?回答是:不多。请看下图,...

    真不难

    C语言难不难?这个问题是相对的,对于找到合适方法学习C语言的同学想必是觉得很简单;但对于一部分同学来说,没有众观全局就会误以为刚入门就需要学习庞大的知识,学着学着开始看不懂,由于心理作怪,感觉内容巨多,之后就真的一直看不懂了。

    但C语言的基础内容真的多吗?回答是:不多。请看下图,C语言可以分为9个块,或者说9个主要知识点;才9个?对的,就是9个。主要是printf输出、变量、scanf输入、数组、逻辑判断、循环、自定义函数、指针以及结构体。

    接下来我将讲解各个知识点的简要概括,助各位学习者一同进步。

    在这里插入图片描述以下将会在讲解知识点的时候有对应知识点的教程链接,点进去就可以看到文章教程,全部免费,无套路~

    先来个教程完整目录

    目录

    第一篇:(一)脱离学习误区
    第二篇:(二)C语言没那么难简单开发带你了解流程
    第三篇:(三)轻轻松松理解第一个C语言程序
    第四篇:(四)语言的基本数据类型及变量
    第五篇:(五)C语言的变量、常量及运算
    第六篇:(六)轻轻松松了解C语言的逻辑运算
    第七篇:(七)C语言的循环分分钟上手
    第八篇:(八)了解基本数组还不是那么简单
    第九篇:(九)C语言二维数组与循环嵌套
    第十篇:(十)C语言的指针原来是这样
    第十一篇:(十一)C语言自定义函数真的很简单
    第十二篇:(十二)原来结构体是这么回事
    第十三篇:(十三)socket服务端编写

    C语言新手的100个报错解法

    推荐

    欢迎大家关注公众号,公众号每满1024及1024倍数则会抽奖赠送机械键盘一份+IT书籍2份哟~
    在这里插入图片描述

    学习目标

    1.知道C语言真不难

    一、printf

    在学习C语言时,第一个程序一般是HelloWorld;HelloWorld主要是编写一个程序,在程序运行时显示HelloWorld文字;使用的代码就是printf。这是程序的第一步,并没有过多的内容,主要是了解软件的使用,以及尝试第一个程序的编写。

    printf教程参考:(三)轻轻松松理解第一个C语言程序

    二、变量

    在这里插入图片描述

    变量这一块的知识点主要是介绍如何使用变量,并且告诉你变量有很多类型,其实变量就是指可以存储值的容器。这个非常好理解,例如你在生活中使用的杯子,杯子用来装水,或者是一些液体;装水可以当做容器的值是水,容器是杯子。那我也可以用抽屉装书本,书本就是值,抽屉就是容器。

    在编程中也一样,不同的容器对应的是不同掉值;在C语言中,存在几个类型,这些类型规定使用指定的容器去存储;当然也可以不按照常规存储,就像你用一个纸杯装了一个红彤彤的碳一样,高温会把纸杯给融化;除非你是故意要这个效果。

    所以变量就是很简单的一个内容。在变量这一节的内容中,还将会学习变量的输出。这个输出值的是,我们在程序运行时将该容器内装的东西显示出来;就像你用一个桶装了你钓鱼钓到的货,你把这个货给大家一起看了。

    变量还有一个关键的概念,就是可变。什么是可变?可变就是值你容器内的东西倒出来后还可以装新的东西进去;我装水的杯子我喝完了还可以装别的水进去。但是常量就不一样,常量存储了值后,就不可以改变了,就已经外包装封死了;你只能看见里面装什么,给大家看,但是你还想把里面的东西拿出来装别的东西进去是不可能的。

    变量教程参考:
    (四)语言的基本数据类型及变量
    (五)C语言的变量、常量及运算

    三、scanf

    在这里插入图片描述

    scanf的作用主要是接收用户的输入。什么是接收用户的输入呢?接收用户的输入就是值我们运行程序后,例如需要输入一个密码才可以启动程序;这时就需要我输入一个值,程序将等待我进行值的输入;输入完毕后程序接收到这个值,判断是否正确。要完成这个操作,在C语言程序中就需要使用scanf。

    scanf主要有几个知识点,最为主要的知识点则是知道变量的地址。一般情况下,我们输入一个值将需要一个变量进行接收;这句话我们可以理解成,输入一个值,我们需要一个变量对这个值进行存储。但是要完成这个操作需要知道这个变量的地址,得到地址后我们就会将这个值存到这个变量中。每个变量在内存中会有一个地址对应,就像你住的地方一样,有一个标记,给予这个标记给scanf后就可以将值存储到那个变量中。

    由于融入到了其它知识点这一个知识点不在这列出:(一)脱离学习误区

    四、数组

    在这里插入图片描述

    数组主要是理解数组结构是如何存储的。数组是用来存储一堆数值的容器,跟单个的变量所存储的内容不一样,数组可以存储多个。例如我们需要存储同一类数据的多个值就可以使用数组。数组的存储结构跟一个抽屉一样,每个抽屉都装了一个值,例如第1排第1个,第1排第二个,理解了就及其简单。

    二维数组呢其实跟一般的数组一致,就是有了第2排,有了第3排等。所以你既然能够理解抽屉,那么数组一定可以理解。

    其中索引指的就是第几个,第几排的这个几,这个数字指的是一个量词对位置的标记;数组的存取就是指对这些抽屉进行查看,和重新放一些东西进去,就那么简单。

    数组教程参考:
    (八)了解基本数组还不是那么简单
    (九)C语言二维数组与循环嵌套

    五、逻辑判断

    在这里插入图片描述

    逻辑判断其实就是对一些数值进行判断,例如刚刚说的,这个程序每次打开需要输入一个值,判断这个值是否是打开的密码,如果输入错误就退出程序。

    那么进行判断就需要使用if或者switch。if和switch都是同样的作用,懂其一则都懂,只是使用格式的不同而已。例如我们打开程序,输入了1234,密码是123456;输入的值存到了一个容器中,这个容器我们给它一个名字,或者说给了标记,叫做A;那我们只需要判断A是否等于123456就可以了。这就是逻辑判断的作用。

    逻辑判断也可以进行“套娃”,也就是判断是否正确后再进行判断,也可以同时判断多个条件。例如当前的密码知道能够被2除断,没有余数就正确,但是不能等于2;这个时候就需要使用逻辑判断运算符,只要把想判断的内容放到逻辑判断符的左右两边,就可以完成了。

    逻辑判断教程参考:
    (六)轻轻松松了解C语言的逻辑运算

    六、循环

    在这里插入图片描述

    循环是为了重复运行一些代码而设计的。主要使用的逻辑为,给予循环你要循环的次数,给予循环的代码,最后给予一个循环的控制变量;循环的控制变量作用顾名思义,用来控制循环次数;我们设置一个容器,里面装了一个数字0,每次循环就加1;例如最开始这个容器的数字是0,循环1次后我们加个1,这是容器装的值就是1了,每次加1则每次递增;那么这个时候我们给予的次数是10,每次循环只要判断这个循环控制变量是否大于10,就可以控制循环的次数了。

    for循环、while循环以及do…while循环都是一样的用法,通过循环变量控制循环次数。循环是可以嵌套的,例如循环嵌套指的就是一个循环里面有另外一个循环,每次外面的循环循环1次,里面则循环指定的次数。

    当我们需要重复设置我们的数组存储的值,使用循环特别方便。例如你需要在一个大规则的每个抽屉都需要放一个值,使用循环分分钟解决。

    循环教程参考:(七)C语言的循环分分钟上手

    七、自定义函数

    在这里插入图片描述

    自定义函数指的是你可以自己创建一个工具包。例如洗衣机是一个有功能的工具,它是用来洗衣服的,每次使用洗衣机把衣服扔进去就可以自动帮你完成任务。自定义函数也一样,实现一个功能后直接拿过来使用就可以了。

    洗衣机功能是洗衣服,但是必须要有衣服才可以洗,衣服就是参数;洗衣机洗完衣服后给你的是干净的衣服,那么干净的衣服就是返回值;就是整个功能的结果。

    自定义函数参考:(十一)C语言自定义函数真的很简单

    八、指针

    在这里插入图片描述

    指针其实就是一个代理人,你可以通过这个代理人访问一些变量,或者对这些变量进行直接的操作,你就是他们的主人;但是在使用指针的时候你必须知道你要操作的东西的地址,不然从何操作;多重指针呢就是你的全权代理人跟另外一个人搭伙,你可以操作另外一个人的代理。

    那为什么说指针危险呢?那是因为你的代理人保留着上一任主人的数据,你直接让他去操作一些东西,他会把上一任主人保留的数据拿去操作,这样你操作了不属于你的东西,这就被警告了。所以要使用指针时记得把上一任主人的数据给丢掉,并且用完这个指针工具人后让它把所有数据都扔掉。

    指针教程参考:
    (十)C语言的指针原来是这样

    九、结构体

    在这里插入图片描述

    结构体我们可以当做是一种类型的组合。例如你使用变量去存储一个人的名字、年龄,需要新建2个变量;例如你又要存储一个人的名字、年龄就需要再新建2个变量;真太麻烦。这时使用结构体,结构体就像一个大容器,跟数组不一样,结构体可以给自己存的值给个变量存储,数组直接就是个变量,结构体包含着其它的变量。我们新建一个结构体叫做“人”,这个人结构体我们在内部新建2个变量,一个是名字、一个是年龄,这时只需要创建这个结构体,那我们就可以直接拥有2个变量,简单方便。

    结构体教程参考:
    (十二)原来结构体是这么回事

    总结

    了解概念后,学习将不会有太大难度,主要是认识使用的语法规则即可。

    展开全文
  • CQRS很难吗?

    千次阅读 2018-08-05 20:21:00
    有些人说“CQRS很难吗?” 是吗?好吧,我之前也一直是这么认为的!但是当我开始编写使用CQRS的第一件软件作品时,一切都改变了。我发现他一点都不复杂。而且我认为在大型团队中保持这种编程行为将变得更容易。 我...

    好久没来这里了,今天登上来发现界面风格变化很大,而且博客也开始支持markdown,越来越先进了。那么就借着这个势头分享下最近一直在研究的DDD-CQRS。

    有些人说“CQRS很难吗?”

    是吗?好吧,我之前也一直是这么认为的!但是当我开始编写使用CQRS的第一件软件作品时,一切都改变了。我发现他一点都不复杂。而且我认为在大型团队中保持这种编程行为将变得更容易。

    我也曾思考为什么人们普遍认为CQRS很难,后来我想到是为什么了。因为有很多规则!人们讨厌规则,现实社会中已经很多了,所以很多人沉迷于虚拟世界之中。规则让我们不舒服,因为我们必须遵守它。在这篇博文中,我将从几方面论证这些规则是容易理解的。

    一般来说,我们认为CQRS是读写分离架构的一种实现方式。当我以这种方法来理解的时候我发现在简单的CQS实现和真实的CQRS之间还是有几个很重要的步骤需要区分对待的。这些步骤介绍了我之前提到的规则。

    我们的旅程从下面这幅图开始:
    这里写图片描述

    上面是一张我们都很熟悉的经典N层架构图。如果往其中加入一些CQS的话,我们就简单地实现了将业务逻辑分离为命令和查询:

    这里写图片描述

    如果你在维护一个旧系统这可能是最难的一步(因为老代码基本上都是意大利面条似的)。同时这一步也可能是最有效果的,因为你从中对自己的代码有了一个整体的梗概。

    下面先来介绍下命令(Command)和查询(Query)的定义吧!

    首先,发送命令是唯一改变系统状态的方式。Commands对所有系统的变更都要负责。如果没有command,系统的状态就一直保持不变!Command不应该返回任何值。我使用两个类来实现:Command和CommandHandler。Command仅仅是被CommandHandler是用来作为一些操作的输入参数。在我这里,command仅仅是领域模型中调用的一系列特定操作。

    query相当于读操作。通过读取系统的状态,过滤,聚合,转换数据,最后以某种特定的格式传输。它可以被执行多次并且不会影响到系统的状态。我通常在一个类中使用多个execute(…)方法来实现,但我现在却认为将Query和QueryHandler、QueryExecutor分开来讲或许是对的。

    回到上面的那张图,我需要澄清一些事;我私自加进去了额外的变化,就是Model变成了Domain Model。model代表了数据的容器,而domain model则包含了复杂的商业逻辑。这点变化对于我们感兴趣的架构来说没什么直接的影响,但是值得注意的是由于command接管了修改系统状态的职责,主要的复杂性都集中在了Domain Model中。

    稍后你就会发现Domain Model对于写模型来说很有用,但是对于读来讲却表现不是很好。
    这里写图片描述

    我们可以使用这种分离模型,通过ORM映射来构造查询,但是在某些场景,尤其是当ORM遇到负载失衡的时候,下面这个架构可能会更合适:

    这里写图片描述

    现在我们成功地在逻辑层面分离了Command和Query,但是他们还在共享同一个数据库。这意味着实际上读模型在使用的是DB的物化视图(也可通过数据库层面的读写分离代替视图)。当我们的系统不需要解决性能问题,而且我们记得在写模型变更的时候更新我们的查询的时候,这个解决方案还可以。

    下一步是介绍完整的分离数据模型:

    这里写图片描述

    CQRS != Event Sourcing

    Event Sourcing(事件溯源)经常伴随着CQRS出现。ES的的定义很简单:我们的领域产生的事件即表明了系统中发生过的变化。如果我们从刚开始就记录了整个系统并进行回放,我们就会拿到当初系统的状态记录。可以想象下银行账户,从刚开始的空账户,通过回放每个单一事务得到最终(也就是目前)的收支情况。所以,只要我们存储了所有的事件,就能得到系统当前的状态。

    这里写图片描述

    但是对于CQRS来说,领域模型到底是怎样存储的不是特别重要,ES仅仅是其中的一个选项。(也可以使用in-memory或mongo,redis等方式)

    写模型

    由于写模型定义了领域模型的主要职责,并且做了很多商业决定,它是系统的心脏。它体现了系统的真实状态,这些状态可以用来做出有意义的决定。

    读模型

    刚开始我使用写模型来构建凑合的查询,在不断的尝试之后,我们发现这很费时间。因为我们是工程师,优化是第二需求。我们设计的模型在读取时将时间消耗在了关联查询上。我们被迫预先计算出一些有报表需求的数据,这样会使它在查询时表现得很快。这很有趣,因为我们在这里使用到了缓存。依我看来这是对读模型最好的诠释:它就是一个合理存在的缓存。缓存在这里没有细讲,是因为我们还没有触及到项目的发布,非功能性需求不应该过早设计。

    事实上,读模型可以设计的很复杂,你可以使用图数据库(类似Neoj)来存储社交网络,而使用RDBMS(关系型数据库)来存储财务数据。

    设计良好的读模型是需要一定的考量的。如果你的项目不是很大,写模型已经可以胜任几乎所有的读取需求,那么设计个读模型将会导致大量的拷贝代码,这种做法无疑是在浪费时间。但是如果你的写模型存储了一系列的事件,那么你将毫不费力得从中获取到任何时间点上的数据,而不用将事件从零开始进行回放。这个过程被称作Eager Read Derivation,也是我认为的在CQRS最复杂的一块。读模型即如我之前所说,是另一种形式的缓存。而Phil Karlton曾说过“在计算机科学中只有两个问题值得我们关注:缓存的时效性和命名问题”

    最终一致性

    如果我们的模型处于物理上隔离的状况,那么同步就需要花费一些时间,但是这段时间对于某些业务来讲是不能耽误的。在我的项目中,如果所有的部分都运行得很正确,读模型处于不同步的状态是可以忽略不计的。然而,我们必须将时间上的差异性考虑进去尤其是在开发更复杂的系统时。我们设计的UI也是为了能够及时的处理最终一致性。

    我们不得不承认即使在写模型更新的时候读模型也相应更新的情况下,用户也是难以接受老旧数据的出现。更何况我们根本不确定展现在用户面前的数据是否是最新的。

    下面我将要讲述一些实际的代码例子:

    我是怎样将CQRS引入我的项目中的?

    我认为CQRS是简单的以至于不需要引入任何框架。你可以从少于100行的代码开始慢慢地实现它,当需要时再去扩展新功能。你不用做任何努力(学习新的技术),因为CQRS已经简化了软件开发。下面是我的实现:

    public interface ICommand {
    
    }
    
    public interface ICommandHandler
        where TCommand : ICommand {
        void Execute(TCommand command);
    }
    
    public interface ICommandDispatcher {
        void Execute(TCommand command)
            where TCommand : ICommand;
    }

    我定义了两个接口用来描述命令和他的执行环境。这么做是因为我想保持参数的扁平化,不想要任何依赖。我的命令处理器(command handler)能够从DI容器中请求依赖,根本没有必要手动初始化它(除了在自测用例中)。实际上,ICommand接口出现在这里无非是想告诉开发人员我们把这个类当做command来用。

    public interface IQuery {
    
    }
    
    public interface IQueryHandler 
        where TQuery : IQuery {
        TResult Execute(TQuery query);
    }
    
    public interface Interface IQueryDispatcher {
        TResult Execute(TQuery query)
            where TQuery : IQuery;
    }

    这里讲IQuery接口作为返回的query结果类型。但这不是最优雅的方法,但是在编译器类型被确定了。

    public class CommandDispatcher : ICommandDispatcher {
        private readonly IDependencyResolver _resolver;
    
        public CommandDispatcher(IDependencyResolver resolver) {
            _resolver = resolver;
        }
    
        public void Execute(TCommand command)
            where TCommand : ICommand {
            if(command == null) {
                throw new ArgumentNullException("command");
            }
            var handler = _resolver.Resolver>();
    
            if(handler == null) {
                throw new CommandHandlerNotFoundException(typeof(TCommand));
            }
    
            handler.Execute(command);
         }
    }

    这里的CommandDispatcher相对来说是短小的,它只有一个职责就是为command初始化合适的command handler并执行。为了避免手写command注册和初始化过程,我使用了DI容器来帮我做了。但是如果你不想使用DI容器你可以自己来实现。我认为这并不难。只有一个问题,那就是通用类型是比较难定义的,这在刚开始这么做时可能有些挫败感。但这种实现使用起来已经很简单了,这里是一个简单的command和handler的例子:

    public class SignOnCommand : ICommand {
    
        public AssignmentId Id { get; private set; }
        public LocalDateTime EffectiveDate { get; private set; }
    
        public SignOnCommand(AssignmentId assignmentId, LocalDateTime effectiveDate) {
    
            Id = assignmentId;
            EffectiveDate = effectiveDate;
        }
    }
    public class SignOnCommandHandler : ICommandHandler {
    
        private readonly AssignmentRepository _assignmentRepository;
        private readonly SignOnPolicyFactory _factory;
    
        public SignOnCommandHandler(AssignmentRepository assignmentRepository,
                                    SignOnPolicyFactory factory) {
            _assignmentRepository = assignmentRepository;
            _factory = factory;
        }
    
        public void Execute(SignOnCommand command) {
            var assignment = _assignmentRepository.GetById(command.Id);
    
            if(assignment == null) {
    
                throw new MeaningfulDomainException("Assignment not found!");
            }
    
            var policy = _factory.GetPolicy();
    
            assignment.SignOn(command.EffectiveDate, policy);
        }
    }

    只需要将SignOnCommand传入dispatcher就可以了:

    _commandDispatcher.Execute(new SignOnCommand(new AssignmentId(rawId), effectiveDate));
    就是这么简单!唯一的区别就是它返回了指定的数据,依赖于之前定义的通用的Execute方法,返回了强类型的结果:

    public class QueryDispatcher : IQueryDispatcher {
        private readonly IDependencyResolver _resolver;
    
        public QueryDispatcher(IDependencyResolver resolver) {
            _resolver = resolver;
        }
    
        public void Execute(TQuery query)
            where TQuery : IQuery {
            if(query == null) {
                throw new ArgumentNullException("query");
            }
            var handler = _resolver.Resolver>();
    
            if(handler == null) {
                throw new QueryHandlerNotFoundException(typeof(TQuery));
            }
    
            handler.Execute(query);
         }
    }

    这个实现是扩展性极强的。比如我们想引入事务到comamnd dispatcher中,可以像下面这样做,无须动用任何原有的实现代码:

    public class TransactionalCommandDispatcher : ICommandDispatcher {
        private readonly ICommandDispatcher _next;
        private readonly ISessionFactory _sessionFactory;
    
        public TransactionalCommandDispatcher(ICommandDispatcher next,
            ISessionFactory sessionFactory) {
            _next = next;
            _sessionFactory = sessionFactory;
        }
    
        public void Execute(TCommand command)
            where TCommand : ICommand {
            using(var session = _sessionFactory.GetSession())
                using(var tx = session.BeginTransaction()) {
    
                try {
                    _next.Execute(command);
                    ex.Commit();
                } catch {
                    tx.Rollback();
                    throw;
                }
             }
         } 
    }

    通过使用这种“伪切面”,我们可以简单地实现Command和Query dispatcher的扩展。

    现在你明白了CQRS并不难,基本的观点已经讲的很清晰了,但是你还是需要遵从一些规则。这篇博客没有包含全部的你想知道的东西,所以我推荐你读一读下面这些文章。

    参考文献:

    1 CQRS Documents by Greg Young

    2 Clarified CQRS by Udi Dahan

    3 CQRS by Martin Fowler

    4 CQS by Martin Fowler

    5 “Implementing DDD” by Vaughn Vernon

    原文地址:https://www.future-processing.pl/blog/cqrs-simple-architecture/

    展开全文
  • 工作容易,赚钱很难

    万次阅读 2017-11-07 09:10:54
    工作容易,赚钱很难 李宗盛有首歌的歌词里写到:「工作是容易的,赚钱是困难的」。乍一听感觉有点矛盾,工作的一个重要结果不就是赚钱么,为什么工作容易赚钱却难?但仔细一想就恍然其中想表达的意思了。 ...

                                               工作容易,赚钱很难


    李宗盛有首歌的歌词里写到:「工作是容易的,赚钱是困难的」。乍一听感觉有点矛盾,工作的一个重要结果不就是赚钱么,为什么工作容易赚钱却难?但仔细一想就恍然其中想表达的意思了。


    工作的本质是出售劳动价值,通过工作赚到的钱是对劳动价值的价格度量,也即劳动的市场价格。而劳动的市场价格总是围绕价值上下波动,有可能折价也可能溢价,但总不会偏离价值本身太远。所以歌词里的意思可能是,你随便找份工作来养家糊口可能还算容易,但想赚很多钱这可就困难了。而不同劳动种类的市场价格差异也是巨大的,我想先从一些典型的不同劳动种类群体来谈谈他们的工作与赚钱。


    农民工


    最新的数字显示农民进城务工的人数达到 3 亿(参考[1]),这代表了一个很大的工作群体。而因为家庭和工作的原因我接触过一些这个群体的人,所以了解了他们是如何工作并赚钱的。


    过去的十来年城市房地产业的大发展吸纳了一大部分农民工,他们吃住干活都在工地上,年龄跨度从十多岁到五六十岁。干一天活算一天报酬,所以算是个日薪制的工作吧。而不同的工种之间的每日报酬也不同,一些年老的农民工只能干些简单且没那么重体力的活,所以日薪自然低些,大概在 100 元附近吧。而一些重体力和高风险(如:高空户外)的活就需要年轻人,而日薪也相应更高,可能有两、三百不等。干一天算一天钱,对确实只是算,计算的算。每天并拿不到钱,平时只发点伙食费够吃饭而已,剩下的工资需要年底(春节前夕)一次性结算发放。所以每到年底总有些农民工欠薪讨薪的事件,也正是源于此类行业规则的不合理埋下的隐患。


    农民工付出的劳动价值的本质正是他们的体力和时间,时间是有极限的,无非就是干满一年 365 天,而体力也是会随着年龄增长而下降的。所以农民工里年龄过了一定阶段的老年人日薪就是比年轻人低,而他们的工作内容和性质除了风险溢价外并没有其他太多的技能和经验溢价。确实可能有些工种是有一定技能要求的,但多是可以通过短时间的培训很快熟能生巧的技能,而经验在此类工作内容里也是无处沉淀的,自然也带不来额外的溢价。这正是体力劳动者面临的现实,人只要不懒惰通过出售体力是可以养活自己甚至养活一家人的,但还想要赚更多钱实际就困难重重了。


    像农民工这样的体力劳动者的收入总是没那么稳定的。在房地产行业红火的日子出现的民工荒,自然带来价格的上涨,而近年房地产不那么景气后,农民工连找活做都困难了。也就是在行业不景气时连工作都没那么容易了,农民进城找不到工只能回农村,在农村可以种田但一样还受到自然天气的影响,养点鸡鸭猪鹅也会受瘟疫疾病的影响。而且显然的事实是在农村无论种田还是养家禽都比进城务工赚的钱少的多,要不哪来 3 亿的农民工呢。


    今天房地产不那么景气了,而互联网带来的电商新行业还处于上升期。这也带动了一个旧行业的大变化,那就是快递业。也有不少农民工进入这行,相比建筑工地而言工作待遇和环境都提高了不少。至少工资可以按时地拿到,正规点的快递公司还会按规定买上五险一金,冬夏天还有额外的高低温津贴,而且多劳一般都是多得的。也许处于上升快递行业的农民工们工作还是容易的,只是还要赚更多钱则困难,而处于衰退房地产业的农民工们则工作已是不易,何谈赚钱呢。


    程序员


    虽然程序员们喜欢自嘲为码农或码工,但程序员的工作与农民工相比还是有天壤之别的。很多程序员将自己的工作比作搬砖,暗示重复而无趣。但此搬砖相比农民工的真搬砖其中的本质差别在于,程序员即使搬砖也是积累经验的,而经验是会带来溢价的。


    即便你再觉得程序员的搬砖多么无趣,但我们看看实际国内的程序员也不过在几百万人数(参考[2]),相比真搬砖的农民工数量差了两个量级。这里面的制约是什么呢?在去年万众创新,大众创业,互联网+席卷全行业时,每个公司似乎都已万事俱备,只差一个程序员了。真相是一个合格的程序员的培养周期实际比我们想象得要长得多。不少人通过参加编程培训机构的短期(3到6月不等)培训入行,实际初期能赚到的钱可能还真不如农民工在工地上搬砖的水平。虽然我司办公楼对面就有一个北大青鸟培训,但我对这类培训入行的程序员的市场平均价格还是不太清楚,只是凭感觉觉得可能并不高。


    就好像我有好些同事,十年前他们还算是从重点大学的计算机专业毕业进入程序员这行,当时的程序员薪资也就 1k 左右,而那时我机械的同学去深圳富士康干流水线工人的工作每月还有 1.8k 呢。十年下来,程序员的起薪水平随着行业的快速发展涨了很多,而不同级别、背景和经验的程序员之间的薪酬跨度也足够大,年薪从几万到几百万不等。


    最近五年我都有连续参加校园招聘,感受很明显得是校招一年比一年起薪高,导致五年前进来的学生工作三年后拿到的薪酬反而没有两年前刚招的学生高,出现了薪酬倒挂的现象。这就是由行业的火热发展导致的供需失衡,引发了市场价格涨幅远远超过了公司的年度涨薪机制。现在一线互联网公司(如 BAT 等)还会给一些特别优秀的毕业生发出 Special Offer,年薪通常在 50万+,这个年薪我想甚至很可能超过大部分工作了十年的老程序员。


    为什么不同程序员的价值体现出来的价格差异如此之大?这里除了知识、技能、经验的积累差别之外也就还有行业背景的因素。程序员写程序的能力是很难单独变现的,程序附着在软件之上,而软件附着在具体的行业之上。所以在一线互联网公司十年的程序员和在外包 IT 公司十年的程序员,知识、技能、经验的差距也许没有一倍,但收入上可能就有数倍的差距,额外的部分我理解就是程序附着的行业价值链之间的差距。就像 2000 年 PC 互联网兴起时,一个会写 HTML 的程序员就能月入上万,而 2010 年移动互联网崛起时,移动开发相关的程序员缺口很大,一年经验的移动端程序员薪酬能超过五年其他领域的程序员。


    所以,程序员在你赚到的工资中你得分清哪些是来自行业发展的趋势力量,哪些是自身掌握的知识、技能和经验所耗费时间的折现值。吴军博士在他的书《浪潮之巅》中提出的技术行业和公司发展的浪潮规律,总有一些公司很幸运地、有意识或无意识地站在技术革命的浪尖之上,在这十几年间,它们代表着科技的浪潮,直到下一波浪潮的来临。如果你是有幸处在这样的公司,随着公司的发展数年间站上了浪潮之巅,那么也许你就是为数不多的赚到钱的程序员了。浪潮不常有,总是浪潮退去我们才发现原来浪潮已来过,一边遗憾的慨叹一边又充满期望的等待下一次浪潮。


    其实,如果对钱的追求没有达到需要财务自由的程度,程序员只需要持续努力地积累自己的知识、技能和经验就能实现不断的增值,达到一个小康中产的水平。有些人在程序员的道路上中途放弃了,会有一些理由比如觉得太累,也没有什么编程的天赋。关于天赋,网上有句流传甚广的话:「以我们的努力程度还完全没到拼天赋的阶段」。郝培强之前写过一篇流传甚广的文章(参考[3]),关于他的前妻,一个初中还没毕业的女生正是通过北大青鸟培训变身程序员,努力奋斗数年最后挣到年薪 40 万。所以也许持续的努力也是一种天赋吧,大部分人并不俱备,这需要克服我们与生俱来的懒惰。


    管理者


    想必很多程序员进入这行时都听说过这样的说法,当程序员老了,写不动代码了可以考虑转管理。这个说法建立在这样的认识上,老程序员们拼体力(加班)没有年轻人强;拼精力,人到中年家庭和工作各方面需要平衡的因素更多,也不如年轻人更专注;那么只剩下拼经验了,在这点上老程序员占优势。而且貌似经验这种东西在管理岗位上更易于发挥更大作用。


    对这类主观的想法不想做正确与否的评论,只是引发点思考。这里提点客观的方面,一般管理岗总是有限的,100 个程序员中可能只有 5 个管理岗的位置。而管理者的工作也分为两类,这个在梁宁那篇《看清自己的职场宿命》文中有过比较清晰的定义(参考[4]),中低级别的管理偏于「任务管理」侧重于将分配的任务及指标拆解成动作,安排动作序列,配置风险,配比团队人员保证完成任务,达成指标,这个级别的管理者最重要的是责任心和执行力。


    而高级别的管理者则属于「战略管理」,根据战略决策,安排任务优先级,配置资源、鼓舞士气,保证方向。梁宁在其文中总结对于战略管理者最核心的能力就是:「心力」,就是无止尽的操心能力。文中写道:「资源永远有限,战略常常在变,兄弟都是亲的,永远没人满意。」就是这一级别管理者面对的永恒命题。


    而关于「心力」让我们最好理解的就是,在你有了孩子后是不是感觉突然就多了很多事要操心,奶粉喝什么?空气也不好?摔了怎么办?病了怎么办?社会也差劲,抢小孩的也多了,最近连疫苗也沦陷了。教育会不会输在起跑线?学区房买不买?钢琴学不学?奥数学不学?唐诗背不背?母语还说不清就开始考虑英语该什么时候学?每个父母都为孩子提前操了很多心,但很多时候这心很可能还白操了,有时方法没用对还会扭曲孩子的成长,属于费尽心力还未讨得好。管理者其实也面临类似问题,不仅要操心还得好好权衡选择这心要怎么操才合适。


    这么一看管理者实际并不像我们简单想的高高在上,发号施令,躺着就把钱挣了的。若无足够的心力和操控心力的智力与技巧,还是算了吧,即便机缘上位恐怕也未必能够持久。曾经有个程序员老在公司内部论坛吐槽管理太差,后来把他提为研发部一把手,大意就是 「you can you up」。我那年刚入职该公司,后来吃过当年的团年饭后我再没见过这位程序员了,正应了那句「眼看他起朱楼,眼看他宴宾客,眼看他楼塌了」。


    到了「战略管理」级别的管理者通常年薪都是不错的,从百万到千万级。为什么值那么多钱,是因为技能逆天,智力超群,心力无穷么?而且这个级别的人通常来说工作经验都会比较丰富,也不会太年轻了。我揣摩了下觉得这里面的原因可能是岗位和人的双重稀缺性共同导致的市场定价。这个级别的管理者都是决策者,越高位的管理者的一个决策失误带来的代价是巨大的,但人是无法避免犯错的,所以我们只能设法找到决策正确概率更高的人。这里越多经历和经验的人可能犯过的决策失误越多,而每犯一次错误吸取的教训让他下次犯错的概率更小。


    这个理论我感觉还是有效的,这个世界上有个数亿人参与的决策游戏,那就是股市。这个是一个越早参与越有利的事,因为你一定会犯错。早期挣钱少,犯点错损失也小。但每犯一次错都减少了下次犯错的机率(对有自省能力的人而言),若是等工作了十来年,攒了一大笔钱,听说牛市来了想去股市捞一笔,很可能一次错误就被洗白了,恩,去年的股灾网上各种传说洗白了不少中产。


    所以,若你感觉自己各方面都已准备就绪却还没有进入管理者的序列,那么很可能的原因是岗位暂无空缺吧。关于管理者大概就写这么多,毕竟我也不是管理者,只是站在第三方观察者的角度去描述了下我的认知,仅作参考。


    ...


    三类完全不同类型的劳动群体,分别主要依赖「体力」、「智力」和「心力」来工作和赚钱。若只想赚点钱求个生存温饱甚或小康,在如今的社会环境下还不算太困难,难的是若想摆脱钱的束缚与困扰,就需要赚更多的钱。


    参考


    [1] 新华网. [透视2016年春运新变化:3亿农民工的“城”与“乡”](http://news.xinhuanet.com/local/2016-02/09/c_128711019.htm). 2016.02  

    [2] IDC. [全球有1850万程序员 中国占10%](http://tech.ifeng.com/it/detail_2014_01/06/32762698_0.shtml). 2014.01  

    [3] tinyfool. [我前妻的故事,一个初中肄业生的奋斗](http://mp.weixin.qq.com/s?__biz=MjM5MjUwNzIyMA==&mid=400060668&idx=1&sn=9064cf2be8b99bdfb0fdf9eba157eaf6&scene=21). 2015.10  

    [4] 梁宁. [腾讯的职级系统——看清自己的职场宿命](http://mp.weixin.qq.com/s?__biz=MjM5MjA4MjU4MQ==&mid=200790551&idx=1&sn=17cb243a839d12f19a997be4d2572537&scene=21). 2014.08

    展开全文
  • 工作容易,赚钱很难

    万次阅读 2017-11-21 19:40:59
    工作容易,赚钱很难 李宗盛有首歌的歌词里写到:「工作是容易的,赚钱是困难的」。乍一听感觉有点矛盾,工作的一个重要结果不就是赚钱么,为什么工作容易赚钱却难?但仔细一想就恍然其中想表达的意思...
  • 毕业,找工作,很多人都面临相同的问题。自己能做什么?什么工作既舒服,福利又好(不存在的,除非银行你家开的)。然后社会是个发展的社会,现代人的生活越来越智能,生活中其实充满“技术”!!!所以,在各个...
  • 2016-08-26近期一方面是所在的公司招聘Java开发人员很难招到合适的,投简历的人很少;而另一方面,经常听身边的人说Android、iOS方面找工作不好找,特别是没什么经验的,经验比较少的!说是不好找,但在我家所在的...
  • 感觉自己不会的东西太多了,不知道如何下手?

    万次阅读 多人点赞 2019-10-14 09:59:36
    GitHub 8.8k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 8.8k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 8.8k Star 的Java工程师成神之路...实话说,这个问题同样也困扰过我,大概就是我...
  • 可能多刚接触 Spring Boot 的小伙伴都会有这样的疑问,Spring Boot 要怎么学,要...我们刚开始学习 JavaWeb 的时候,使用 Servlet/JSP 做开发,一个接口搞一个 Servlet ,头大,后来我们通过隐藏域或者反射等方...
  • 我在阿里工作的这段时间里,都学到了哪些东西

    万次阅读 多人点赞 2019-08-18 21:38:28
    我也开始承担更多的工作,当自己逐渐习惯这种节奏之后,才感觉自己逐渐在融入这家公司,每次搞懂一个业务问题或者技术问题都会觉得自己在成长,当肩头上承担更多责任的时候,同时也承担了更多压力,如果不能调整好...
  • 面对一个不严厉的研究生导师,怎么做才能学到东西?修改 在知乎上差不多一直潜水,认真回答过几次问题,这是第一次问。马上研究生就要开学了,本人要读本校的研究生,本科成绩一般,没获得保送的机会。 ------先...
  •  -这门课程是越到后来就越发现它的重要,虽然刚开始看时就象看马哲一样不知所云。 我的建议是看《实用软件工程》(黄色,清华)。 不要花太多的时间去记条条框框,看不懂就跳过去。  在每次自己完成了一个软件...
  • 函数指针和指针函数用法和区别

    万次阅读 多人点赞 2018-05-24 08:11:10
    在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越,特别是刚开始学习这门...
  • 标题借鉴了一下老罗的风格,哈哈(*^__^*) 原来围住神经猫游戏火的时候,恰巧当时正在学QML,顺手就给弄了一个,不知道大家还记不记得这个游戏,界面是酱紫的:然后在 Qt 贴吧里面也共享了一下:...
  • 游戏开发那些念的经

    万次阅读 多人点赞 2012-07-07 11:10:11
    游戏&引擎不要为了做引擎而做引擎脱离项目的引擎是一个没有经过验证的东西, 没人敢引擎设计要以人为本, 这不是一个技术问题, 是需要项目的沉淀和积累的技术&应用技术如果不转化为生产力, 那么它的价值就是停留在...
  • 由于项目需要的原因,后来渐渐开始学起 HTML、CSS、JavaScript 这些语法相关的东西接触时没有感觉太大难度。 当时就想着怎么把页面搞好看,搞各种动画炫技。写一个小球从下面弹出来的效果,换各种姿势弹出。当时...
  • 本文是一位银行的HR写的,他工作了10年...现在越来越看清楚“性格决定命运”,性格这东西是熔透与骨髓的,性格的养成和学校教育没有多大关系,大多决定与家庭背景,和成长环境。从大学毕业出来的第一步,往往起到至关作
  • 入职场的你 - 程序员的成长笔记

    千次阅读 多人点赞 2019-04-02 20:08:58
    的确,现阶段,毕业几年的年轻人,面临车,房子等的压力有时候压力挺大的。但你过度焦虑的话,每天生活在恐慌当中,你会发现你生活过得一团糟。对比一下,多国家的底层平民,典型如印度,一点不焦虑,乐天知命,...
  • 8000字干货:那些厉害的人是怎么构建知识体系的

    万次阅读 多人点赞 2019-09-29 11:18:27
    理解如何八大问发现知识的连接点; 掌握致用类知识体系的构建方法; 能够应用甜蜜区模型找到特定领域来构建知识体系。 1. 知识体系?有必要吗? 小张准备通过跑步锻炼身体,可因为之前听说过小腿变粗、膝盖受伤...
  • 而得到的回答却基本上是说很难学,甚至有说要两年才算入门。我开始是学VB的,现在转学QT。谈谈我对C++的看法。 1、入门兴趣和方向 大家知道,VB是一门非常容易入门的编程语言。不需要太多的知识,只学几天就可以...
  • yolo系列之yolo v3【深度解析】

    万次阅读 多人点赞 2018-09-12 16:24:48
    多骚年入手yolo算法都是从v3才开始,这是不可能掌握yolo精髓的,因为v3东西是保留v2甚至v1的东西,而且v3的论文写得随心。想深入了解yolo_v3算法,必须先了解v1和v2。以下是我关于v1和v2算法解析所写的文章...
  • [软件人生]给一个毕业学生朋友的建议

    万次阅读 热门讨论 2007-02-05 09:40:00
    最近遇到了一个刚毕业的小朋友,他的认真和专心程度让我感觉好,下面我贴出我和他从刚开始到最后给他提供建议的一系列对话,上面有时间,看到的朋友可以区分一下时间点,这样会更容易理解.对话用户:所有分组(QQ好友)==...
  • Google Translate是个好东西

    千次阅读 2005-08-13 11:54:00
    对于像我这样刚开始自学语言的人来说,最大的问题就是很难把发音同文字联系起来,毕竟看着文字有助于记忆单词和发音。//sigh,我再也不像小孩儿了,大字不识一个,也能流利会话。一般的教材通常假设有老师教,所以...
  • Django Rest Framework和AngularJS开始你的项目 作者:Kevin Stone 原帖:Getting Started with Django Rest Framework and AngularJS 原帖时间:2013-10-02 译序:虽然本文号称是"hello world式的教程"(这么长的...
  • 程序员的四个暑假:从打工开始到打工结束

    千次阅读 多人点赞 2021-07-14 09:02:02
    暑假,对于很多人来说是个非常好的机会,两个月的时间相对自由,没有课程、考试压力,如果认真利用起来可以学到多内容。 自从离开高中,其实还有一个高三毕业的暑假,那个暑假大部分人可能玩了一暑假或者是做零工...
  • 如果程序员和产品经理都凡尔赛文学对话......

    万次阅读 多人点赞 2020-11-21 16:16:21
    当时的人基本都不懂,所以我好像搞出一点点东西都算是重大发现一样,奇怪得。说起相对论,发论文的历程我觉得还是蛮心酸的。我在发表《狭义相对论》的第一篇论文时,一篇参考文献都找不到,不像现在动不动就有几百...
  • 这个东西是我老板安利我的,我们都是超爱喝咖啡一族,但是杯子里的咖啡渍真的是很难洗掉的,所以我当年基本只用深色的杯子了。但是这个神器,真的是!!!(答主都想骂人)多少年的陈年茶渍咖啡渍感觉都能去掉。我们...
  • 13年毕业,两年时间从外包走进互联网大厂!

    万次阅读 多人点赞 2020-08-25 09:32:20
    有等第一份Offer迟迟不到的忐忑、有租房被骗闹到经侦大队的恐慌、有上班钱不够少吃哪顿饭的挣扎。但同样也有雨后彩虹的收获,有迟迟的等待和抉择中看到offer邮件的喜悦、有因租房楼上楼下大家合力解决并促成一对...
  • 哪些东西,年轻人千万不能碰

    千次阅读 多人点赞 2020-04-14 18:15:47
    我们生活中除了显而易见的黄赌毒、传销等大家都知道千万不能碰的东西,其实还有多隐形的,正在默默侵害我们的东西,今天就来扒一扒。 1、无意义的争辩 和网络喷子互喷,就是其中一种。 去年时候,看到过一张搞笑的...
  • 这本书浅墨了一年多时间完成,最近出版,已经陆续在当当,淘宝,亚马逊,京东上架了,各大实体书店也渐渐有了货。  放一张样书的玉照吧,浅墨自己构思的封面哦 ,梦幻吧:   有不少朋友评论说贴个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,706
精华内容 48,282
关键字:

刚开始很难用的东西