groovy 订阅
Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。 展开全文
Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。
信息
类    别
编程语言
发行时间
2003年
外文名
Groovy
创作者
Guillaume Laforge
Groovy简介
Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使 Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。 [1]  (概述图片来源:)
收起全文
精华内容
参与话题
问答
  • 宋宝华ABC

    万次阅读 多人点赞 2010-03-11 23:28:00
    新浪微博:@宋宝华Barry 编写出版《Linux设备驱动开发详解》, 互动出版网2008年度IT图书风云榜“十大畅销经典”、“十佳原创”、畅销榜操作系统类排名第1;51CTO、中国图书商报、China-pub联合评比 “2008年度...

    新浪微博:@宋宝华Barry           

    编写出版《Linux设备驱动开发详解》, 互动出版网2008年度IT图书风云榜“十大畅销经典”、“十佳原创”、畅销榜操作系统类排名第1;51CTO、中国图书商报、China-pub联合评比 “2008年度最佳技术图书”;本书繁体中文版一直位于畅销版。

               

    主持翻译《Essential Linux Device Drivers》,繁体中文版、简体中文版已出版

           

    参与Linux内核开发:

    Commit of "Barry Song <21cnbao@gmail.com>"

    版本           行数         补丁数量
    
    2.6.31        5            2
    
    2.6.32        2869      24
    
    2.6.33        1474      16
    
    2.6.34        1144      25
    
    2.6.35        10789    18        Chinese No.1
    
    2.6.36        592        14
    
    2.6.37        441        14
    
    2.6.38       14188     19        Chinese No.1
    
    3.0            866          1
    
    3.1            88          6
    
    3.2            397        23
    
    3.3            15          2
    
    Total         32868     164      Chinese No.11

    Linux官方内核ARM SoC子系统内maintainer之一。

    技术顾问,其曾在阿尔卡特/朗讯/贝尔、华为、思科、意法半导体、展讯、四方、富士施乐、代傲电子、飞利浦、南瑞、酷派、宝信、ABB、美国国家仪器、建设银行、百富等许多知名企业实施Linux讲座。

    展开全文
  • 宋宝华:Docker 最初的2小时(Docker从入门到入门)

    万次阅读 多人点赞 2017-02-21 09:42:31
    最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级...

    最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级用法,深层原理,一轮轮迭代。坚决反对一上来就搞几百页厚的东西把人脑子弄乱。

     

    Docker是什么?

     

    KVM, Virtualbox, Vmware是虚拟出机器,让每个实例看到一个单独的机器;而Docker是虚拟出操作系统,实现应用之间的隔离,让各个应用觉得自己有一个自己的操作系统,而且彼此之间隔离。假设没有Docker,然后有进程1和进程2,它们的运行将类似下图,进程1和进程2共享kernel,它们是同一OS下2个进程,因此必须拥有不同PID,但是又共享网卡,共享IP地址,看到一样的根文件系统(不chroot的情况下)等,可以用Linux IPC手段进程间通信。

     

     

     

    有Docker的情况下,假设进程1和进程2运行于不同的容器,那么进程1和进程2都觉得自己和对方没有半毛钱关系,都觉得自己拥有自己的根文件系统,自己的网卡等,然后进程1和进程2的PID还可以一样,比如假设2个都是100。但是,此100非彼100。

     

     

     

    Virtualbox等虚拟机的思路则完全不一样,如果进程1和进程2运行于不同的虚拟机,则操作系统都是双份的,它们感觉自己在不同的虚拟电脑上面跑。

     

     

     

    由于可见,Docker达到了类似虚拟机的效果,但是又没有虚拟机的开销,它虚拟的层次更加高。Docker不虚拟机器,仅仅虚拟应用的运行环境。

    为什么Docker也可以“虚拟化”?

    虚拟化,本质上一种虚幻,给你一种幻觉,让你觉得拥有的很多甚至拥有全世界,哪怕你实际是一只蝼蚁。

    经过本人多年研究,虚拟化的技术分为2种,一种是虚拟一个世界,第二个是虚拟一个氛围。

    比如我们在现实生活里面是个屌丝,但是在虚拟人生的游戏里面,我们可以是王思聪++,集美貌智慧财富正义于一生。虚拟人生的游戏,构建一个整个的新世界,这个世界,人人有房住,天下没有贼。那么这个就是硬件都变了,你的内核都变了。这个是Virtualbox,KVM这种虚拟出一个新世界的思路。

    虚拟一个氛围,是Docker的做法。例如贵公司的Linux部门以前只有3,4个工程师,然后有一个manager,后来有30个人了,你就可以分什么内核组、驱动组、应用组等更多的组,然后又多出几个manager。这种组,类似于名称空间,在每一个单独名称空间的manager,都觉得自己是个manager,于是他会爽那么一点点。

    最开始是这样的

     

    后来是这样的

     

    如果这样还不够,还可以搞声卡驱动组manager,网卡驱动组manager,反正可以不停地搞。大家在各自的container里面占山为王。

    Docker就是这样的名称空间让各自在同样的Linux平台上面各自暗爽,装到你自己的容器里面爽。

    安装Docker

    如果是Windows主机,可以下载docker-toolbox一路安装,安装过程中如果提示什么错,可以把360等类似软件关闭。Windows安装好Docker后,使用Docker Quickstart Terminal运行。

    如果是Ubuntu,可以按照https://docs.docker.com/engine/installation/linux/ubuntu/网页进行安装。最简单的Ubuntu 16.04就是命令:sudo apt-get update&& apt-get install docker。

     

    Ubuntu安装Docker后,可以把当前用户加到docker用户组以便当前用户也有权限操作docker client和host之间的通信socket(之后请重启docker相关服务):

     

    sudo usermod -aG docker $USER


    为了装逼需要,我们在docker hub网页注册一个用户名,我注册的用户名是21cnbao。这样以后,就可以自己提交自己的image了。

     

     

     

     

    Docker的架构

    Docker中可能涉及到3个机器或者更多机器,一个运行docker命令的client, 一个包含images并以容器(container)形式运行image的主机,一个docker的images仓库。client与docker host上面的docker daemon通信。当然docker client和host可以运行于一台机器(我们做实验的时候是一台),默认的docker仓库是Docker Hub。

     

     

    一般的流程中,client发pull命令从仓库把image拉到docker host,然后通过run命令指挥image到host上面弄一个container来跑这个image。

    当然也可以是相反的流程,client 通过build命令在host上面创建一个自己的image,然后通过push命令把image推到仓库。之后这个image可以被别的人或者自己pull。

    image到底是个什么鬼?

    Docker镜像是一个特殊的文件系统,提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。image为特定目的而生,比如弄了个nginx的image后,这个image就把nginx的东西包罗万象了,无论是张三、王五、六麻子还是七癞子,无论它是什么电脑,什么操作系统,只要支持docker,它把这个nginx的image下载下来后,拿docker run命令就可以弄容器跑nginx了。这样,用户就不用装nginx以及它依赖的一切包了(通常装一个软件弄依赖也能把你弄地烦躁死了)。这样看起来,Docker实在是居家旅行,杀人越货之必备良器也!

     

    镜像构建时,会一层层叠加,前一层是后一层的基础。

     

    每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。所以这个很类似git里面这一次提交相对于上一次提交的diff:

     

    $git diff
     layout/book_index_template.html                    |    8 ++-
     text/05_Installing_Git/0_Source.markdown           |  14 ++++++
     text/05_Installing_Git/1_Linux.markdown            |  17 +++++++
     text/05_Installing_Git/2_Mac_104.markdown          |  11 +++++
     text/05_Installing_Git/3_Mac_105.markdown          |   8 ++++
     text/05_Installing_Git/4_Windows.markdown          |   7 +++
     .../1_Getting_a_Git_Repo.markdown                  |    7 +++-
     .../0_Comparing_Commits_Git_Diff.markdown        |   45 +++++++++++++++++++-
     .../0_Hosting_Git_gitweb_repoorcz_github.markdown |   4 +-
     9files changed, 115 insertions(+), 6 deletions(-)


    这些叠加的最后一层就是container,所以你在container里面改了文件,其实不会进image。

     

     

     

    一次完整的docker实作

     

    说了那么多后,我们必须亲自动手玩了。下面把pull,run,build,push都玩一次,破除神秘感。一个典型的运行流程如下:

    1.    client用pull命令从仓库把image拉到docker host

    docker pull的格式是:

    docker pull[选项] [Docker Registry地址]  <仓库名>:<标签名>

    默认地址是 DockerHub。 仓库名:这里的仓库名是两段式名称,既 / ,“/”前面一般是用户名。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

    下载 Ubuntu14.04的image(以Ubuntu为例):

     

    baohua@ubuntu:~$docker pull ubuntu:14.04
    14.04:Pulling from library/ubuntu
    c60055a51d74:Downloading [>                                                 ] 539.8 kB/65.69 MB
    755da0cdb7d2:Download complete
    969d017f67e6:Download complete
    37c9a9113595:Download complete
    a3d9f8479786:Download complete                                                                
    …


    运行docker images命令看看下载的images:

     

     

    $docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    ubuntu            ml 14.04              b969ab9f929b        4 weeksago         188 MB

     

     

     

    2.    在docker host上面运行Ubuntu 14.04于containers

     

    我们现在运行Ubuntu14.04中的bash shell,因为docker运行image于容器时,需要指定主进程(本例的主进程为bash)。

    在终端1上面运行

     

    docker run -it --rm ubuntu:14.04 bash


    在终端2上面运行

     

     

    docker run -it --rm ubuntu:14.04 bash


    这样我们就运行了ubuntu14.04这个image的2次实例(得到2个容器), Linux下面的ps命令是看进程的,docker下面就是看image的实例容器了。

     

     

    $ docker ps
    CONTAINER ID       IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    e3a913872698       ubuntu:14.04       "bash"              11seconds ago      Up 10 seconds                           wizardly_elion
    db1c25753e97       ubuntu:14.04       "bash"              21seconds ago      Up 21 seconds                           adoring_shannon


    image和container之间的关系类似程序与进程之间的关系,一个静若处子,一个动如脱兔。比如程序QQ,运行一次就是1个QQ进程,再运行一个QQ就是第2个QQ进程。同样道理,一个image也可以运行多份container。

     

    3.    构建自己的image

    现在想在Ubuntu 14.04中增加vim和gcc,构建一个增量image,因为目前的Ubuntu image里面没有这样的命令:

     

    root@e3a913872698:/# vim
    bash: vim: command not found


    于是在Ubuntu 14.04这个image基础上面,叠加一层,然后把它提交到docker hub的21cnbao的仓库。

     

    我们需要在客户端电脑上面创建一个Dockerfile文件(该文件用于描述image),以实现在现有的Ubuntu 14.04上面做增量的目的。

     

    $ mkdir myubuntu
    $ cd myubuntu/
    $ touch Dockerfile


    用vim编辑Dockerfile,添加如下内容:

     

     

    # ubuntu 14.04 with vim and gcc
    FROM ubuntu:14.04
    MAINTAINER Barry Song<21cnbao@gmail.com>
    RUN apt-get update && apt-getinstall –y vim gcc


    RUN 指令的含义是在指定在源image内执行一条命令,本例更新APT 缓存,并且安装vim和 gcc以形成一个增量image。

     

    下面build这个image:

     

    $ docker build -t 21cnbao/myubuntu:14.04 .
    time="2017-02-21T06:48:07+08:00"level=info msg="Unable to use system certificate pool: crypto/x509: systemroot pool is not available on Windows"
    Sending build context to Docker daemon2.048 kB
    Step 1/3 : FROM ubuntu:14.04
     ---> b969ab9f929b
    Step 2/3 : MAINTAINER Barry Song<21cnbao@gmail.com>
     ---> Running in f1449746b58c
     ---> 5dacd7a6ee5d
    Removing intermediate containerf1449746b58c
    Step 3/3 : RUN apt-get update &&apt-get install vim gcc
     ---> Running in b1469caf3509
    Ign http://archive.ubuntu.com trustyInRelease
    Get:1 http://archive.ubuntu.comtrusty-updates InRelease [65.9 kB]
    Get:2 http://archive.ubuntu.comtrusty-security InRelease [65.9 kB]
    Get:3 http://archive.ubuntu.com trustyRelease.gpg [933 B]
    Get:4 http://archive.ubuntu.com trustyRelease [58.5 kB]
    Get:5 http://archive.ubuntu.comtrusty-updates/main Sources [485 kB]
    …


    下面运行21cnbao/myubuntu 14.04这个镜像:

     

     

    docker run -it --rm 21cnbao/myubuntu:14.04 bash


    发现gcc和vim都有了:

     

     

    $ docker run -it --rm 21cnbao/myubuntu:14.04 bash
    root@f33ee07caf43:/#gcc
    gcc: fatal error: no input files
    compilation terminated.
    root@f33ee07caf43:/#

     

    4.    通过docker push把image提交到仓库

    在docker hub上面创建一个仓库myubuntu,该仓库创建后,全名将为21cnbao/myubuntu。

     

    下面push这个image到docker hub,之前我们需要登录到docker hub:

     

    $ docker login --username=21cnbao --email=21cnbao@gmail.com
    Flag--email has been deprecated, will be removed in 1.14.
    Password:
    Login Succeeded

    下面开始push:

     

     

    $ docker push 21cnbao/myubuntu
    time="2017-02-21T07:17:59+08:00"level=info msg="Unable to use system certificate pool: crypto/x509: systemroot pool is not available on Windows"
    The pushrefers to a repository [docker.io/21cnbao/myubuntu]
    87157b68b121:Pushing [>                                                 ] 1.109 MB/134.7 MB
    c9fc7024b484:Pushing [==================================================>] 3.072 kB
    ca893d4b83a6:Pushing [==================================================>] 4.608 kB
    153bd22a8e96:Pushing 7.168 kB
    83b575865dd1:Pushing [==================================================>] 209.9 kB
    918b1e79e358:Waiting
    …


    通过docker hub进哥的仓库看一眼,发现大功告成了。

     


     

     

    2小时结束,相信你已经爱上Docker。相爱容易相处难,痛苦才刚刚开始。人生若只如初见,何事秋风悲画扇。等闲变却故人心,却道故人心易变。

     

    后面如果有时间,再完成一个《Docker 相处的8小时》。

    更多精华文章请扫描下方二维码关注Linux阅码场

    展开全文
  • 宋宝华:论程序员的时代焦虑与焦虑的缓解

    万次阅读 多人点赞 2017-05-25 18:02:50
    生活在2017年的程序员,不焦虑的确实没有几个。经历了2016年的房价暴涨以及此前房价的数次狂飙猛进,能心静如水的人那内心的强大恐怕不是一般人可以企及。本人一介码农兼教书匠,时常走街串巷,曾经在好多公司讲过...

    生活在2017年的程序员,不焦虑的确实没有几个。经历了2016年的房价暴涨以及此前房价的数次狂飙猛进,能心静如水的人那内心的强大恐怕不是一般人可以企及。本人一介码农兼教书匠,时常走街串巷,曾经在好多公司讲过同样的一句话,“在中国,一个程序员的成功不取决于你的代码是否写的好,而取决于你是否在正确的时间、正确的地点、买了一套正确的房”。那么,这个悲哀就在于此,我们究竟是要写好代码,还是要买好房子?还是,其实我两个都做不好?

    坦白讲,焦虑的源头实在是很多。比如,很多人有低电量焦虑症,手机电池只有70%的时候就开始焦虑,总是喜欢到哪里都插上去充电。还有的人有无WiFi焦虑症,断了网络就茫然失措。但是无数此类焦虑的总和,也抵不上我们在这个时代之下,风雨飘扬,难以取舍投机还是勤劳,无法分辨正确的方向在哪里,不知道下一代要怎么办,不知道未来自己的终极归宿在哪里的恐惧要来得强烈。

    得失之间

    这是一个最好的时代,也是一个最坏的时代。每个人如你我,都不过是这个时代里面的一粒尘埃,多少年以后,我们在历史上不会有任何的记忆。但是这样的时代,在中国5000年的文明史上,不知道经历了多少个轮回,放在这个广阔的背景上面来讲,我们今天焦虑的事情都算不得什么。很多事情要长远地思维,当年很多资本家焦虑自己不是三代贫农,现在很多贫农焦虑自己不是资本家;当年很多人焦虑自己没有商品粮,现在很多拿了城市户口的大学生焦虑自己再也成不了农民。很多时候,我们喜欢放大我们得不到的东西对我们造成的影响,而忽略我们得到的东西的正面价值。所以,很多事情,今天看也许是一个巨大的焦虑,但是数十年后,你可能因为你得到的东西而焦虑。育良书记如果没有进官场,成为副部级干部,他会不会每天晚上焦虑地要在院子里面刨坑挖地?得与失都是双刃剑,得了暂时不焦虑,也可能埋藏祸根;失了暂时焦虑,也可能赢来新的转机。上帝为你关闭了一扇门,就一定会为你打开一扇窗。

    焦虑的源头

    废话说了这么多。程序员确实够焦虑的,每一个都能压死咱们:

    工资不上不下,房子好像买得起又好像买不起(如果干脆工资低到买不起,压根就不考虑这个问题了)。

    新技术每天都在迎面扑来,各种概念层出不穷;老板每天让我加班,做的事情好像也学不到东西。

    隔壁家的阿狗没什么文凭,就靠炒房子也身家千万了。后悔当初哥怎么没买那个房子?

    老是高级工程师职位,老子干活这么卖命,工作年数也这么多了,就不能给老子升个士大夫工程师?

    小孩子看着看着大了,该读书了,京沪等地读书怎么办?竞争的人太多了,上地张江的牛逼父母太多了,玩不过他们。

    这些焦虑并举的情况下,给我们程序员的研发事业造成了极大的伤害,就是我们没有办法静下来钻研技术了。既然读书可能无用,那么代码写地再牛逼可能也不是很有用,毕竟早一年买一个五六百万万的房子,一年后double,够很多工程师coding一辈子了。那么我们天天拼命地coding,并且ignore了买房子,还有什么希望?

    我们坦诚地承认这些焦虑都是客观存在的,有一些可能短时间之内都无法修复。那么我们在客观已经存在这些焦虑的情况下,探讨一些缓解之道。

    消沉下去还是积极地自我暗示?

    首先当然是从心理层面上要缓解,建立乐观、豪迈的心态。任何时候要保持,管他妈的,过一天是一天,过一天开心一天的想法,不要为明天忧虑,因为明天自有明天的忧虑。

    不要人为自我放大得不到的东西的负面影响。比如升不了士大夫工程师,那么我们想一想,升了又能怎么样?就马上能不焦虑了吗?就马上高人一等了吗?不升难道就真地一天都过不下去了吗?任何事情都是一个动态的过程,在A公司的高职位,去了B公司可能什么都不是;在B公司的职位低,可能到了C公司迅速发挥作用被认可,很快提升。坚信是金子一定会发光。

    宽以待人还是一切为了个人利益?

    作为一个工程师,已经是混地很惨了,如果在公司没有三五个好友,互相支持,互相取笑,互相打闹,还一定要把自己竖起来,装逼到底,那么这个日子也不见得好过。我们在公司的朋友,很可能是未来帮我们度过最大难关的人。我个人比较侥幸认识了生命中的一众好朋友,他们在关键的时候帮助了我,可以说,没有他们,我前面很多的沟沟坎坎都要走不过去。这里要重点感谢一下露一丝,情魔,昭哥,总舵主,皇上,华谊兄弟,老徐等。没有他们的support,我早就已经挂了。

    那么,我们是否可以为了个人的升职、个人的涨工资而牺牲同事的利益,我认为大可不必。人生是一个长跑,通过扔香蕉皮绊倒别人而跑到前面的做法,算不得光明正大。踩了香蕉皮的人,也多半不会是一个傻子。那么,扔香蕉皮的人,可能后面踩到更大的西瓜皮,如果得失守恒的话。

    珍惜身边的同事,他们可能是最终能够帮助我们的人,是友非敌,尽管短期也可能有利益冲突,但是最后得到的可能要多得多。

    学底层技术还是学赚钱的技术?

    我个人的想法是不能放弃赚钱的想法,比如明明搞硬件前途微妙了,你还一定要跑过去学高速PCB设计。那么选择方向的时候,肯定不得不考虑赚钱。比如,茶总曾经讲过一个这样的故事,当年有个小弟问他是搞Linux内核好,还是去搞上层的JAVA还是什么Python好,然后茶总跟他说,当然是去搞上层。以后这个小弟每次见他面都邀请他吃饭,感谢他当年指点了一条明路 J

    赚钱的方向固然是重要的,但是打好基础可能也是更加重要。如果计算机的基本原理不通,操作系统的基本工作机理搞不清楚,甚至连PV操作,互斥同步什么的都搞不清楚,那么很有可能在搞任何方向的时候,都是在摸瞎。

    有很多程序员在干活的时候,从来不思考,也不提炼和升华自己的知识体系,这样其实搞什么都是云里雾里,这样也很难在技术上面有所建树,很可能更好的方向是改行。技术方向虽然浩如烟海,但是各个技术方向,总是能够发现惊人的相似,基础好的人,学习能力强的人,貌似学什么都特快?

    在一个地方死磕还是看大世界?

    Coding这个事情,既要能沉得下去,又要能出得来。Coding时静若处子,玩乐时动如脱兔。Coding不是生活的全部。

    技术方向和投资理财一样,鸡蛋放一个篮子里面,也有极大的风险。所以,今天我们在玩命解一个bug的时候,也可以多看书,了解前沿技术,扩大自己的视野,先蛰伏起来,等待机会。

    所以比较好的技术组合应该是,在一个方向非常精通,在几个方向比较了解。如果咱们在Linux写个USB驱动,然后别的驱动都不看,内核的机理也不看,上层的编程也不看,D-BUS什么也不看,那么就蕴藏了较大的职业风险。

    另外,Coding也不是全部的世界,放开了看,也有一片天地。我兄弟的老婆,她开了个食品店,有实体店,也在网上买各种吃的,这是个好事,我们热烈的欢迎。这一方面可以增加生活的情趣,另外一方面可以赚钱养家。生活不是只有眼前的代码,还有买卖与玩乐。开uber的,和我们coding的同样高贵。有一天,我也想去开uber。

    看课外书也可以缓解焦虑。JD、淘宝买一本书,真的没有多少钱,吃一顿小龙虾,就是好几本书。最近我就是看那个《万历十五年》,看一些VR、人工智能、人类文明的书,每次看的时候,都发现自己没那么焦虑了。

    既然房子折腾成这个样子,那还要不要学习?

    如果我们的发展方向就是搞技术,明确的说,学习不见得立即能有机会,但是不学习一定没有机会。这个道理很简单,作为一个练武之人,如果功夫不行,就不可能参加华山论剑。我们做程序员的,本质上是一个匠人,能比的也就是自己的招数了,不会降龙十八掌,至少也要练一个九阴白骨抓。

    别人房子已经买前头了,我们现在学习还来得及不?可以说不学习可能是永远也来不及了,学习并且武装自己,还有追上的机会。

    这么问题就来了。每天装逼的领导给我塞这么多垃圾活,我都做不完,哪里有机会学习?同样的道理,如果不学习,可能永远都是打杂的垃圾活,学习并且提升,领导突然发现,原来这哥们不是只会打杂的,还可以不打杂。匠人赢得尊重的方法,可能就是技能。《长城》里面那个讲英语的老外,两剑一射出去,那个彪悍,马上就被统帅张涵予、下一任统帅——因为永远捧不红而红的景甜同志所认可。

    学习的时间,只能靠自己业余时间去挤了。蹲茅坑可以看书,外面晒太阳可以看书,周末出去趟草坪也可以看书,总之,一个人如果想学习,那是神仙也拦不住他的。

    设定目标,让自己忙起来也是缓解焦虑的好办法。闲着容易生病,也容易焦虑,所以一段时间,设计一个目标,而且为了这个目标而严格要求自己并最终实现,可以缓解焦虑。比如这3个月要把英语提高到什么水平,这2个月要看完哪本技术图书,这1个星期要写完哪一篇技术博客等。

    运动、大宝剑、吸毒、吃小龙虾哪个可以缓解焦虑?

    答案是运动和小龙虾。

    上个星期,我弄了个共享单车,然后我就骑啊骑,骑了4-5个小时,在浦东拍了很多图片,传朋友圈了。很多朋友都说这究竟是哪里,这么美,还以为我又闪到外国去了。其实这就是他们每天身处的浦东。生活不是没有美,可能是每天都没有去发现它的那个美。我是一个宅男,但是我的切身体会是,走出去贴近自然可以极大的缓解焦虑。

    至于大宝剑,这个程序员大体不会如商人一般洒脱,办事时谈笑风生,完事后大步流星。对于程序员,由于自己的性格就是战战兢兢那种,完事了可能不仅不会缓解焦虑,反而会加重更多的焦虑。吸毒这个呢,不用说了,看电视电影里面那些人,都吸成什么鬼样子了,不要说缓解焦虑了,很可能酿成灾难。所以这些缓解焦虑的方法,都不适合程序员。

    我们不大宝剑,也不吸毒,但是也不能把生活搞地太苦行僧,该K歌K,该烧烤烧烤,该吃小龙虾吃小龙虾。一段时间之内,忘却bug,放松了再回来,闹不好bug迎刃而解。人类在茹毛饮血的时代,就是群居动物。骑着骏马,来到大草原,烤起羊腿,跳起舞,这个肯定是可以极大地缓解焦虑。

    没有一个亿,我怎么能不焦虑?

    这个我也不知道,因为我就是一个屌丝。很多文献显示,穷人也许焦虑,但是很多富人日日都很焦虑。就我这种屌丝而言,我常常想,我赚了一个亿可能就不焦虑了。但是,无数的教训也告诉我们,赚了一个亿也不见得不焦虑。但是我觉得,还是先让我赚一个亿吧,我宁愿焦虑:-)这个可能和宁愿在宝马里哭,也不愿在自行车上笑一个概念。

    但是没有赚一个亿的时候,整天为了一个亿而焦虑也不是个办法。毕竟幸福感来源于自身,来源于家庭,幸福感是一种由心而生的感受。把自己搞地很阳光,安排和策划好家人的各种活动,也都是增强幸福感。还没有赚一个亿的时候,咱们也不能为了一个亿而忽视任何一个家庭成员。因为,到头来,万一一个亿也没赚到,家庭还搞地很惨烈,那么我们可能不得不每天都是焦虑了。

    简单来说,我们随时做好赚一个亿的准备,但是也留好赚不到一个亿的后路。在没有一个亿的情况下,也要自我营造幸福感。

    还要不要买房?

    刚需,能贷款,能有首付,那就买。因为没什么可以想的。200年以后,你我的房子都不是你我的,也不是你我家人的。200年前中国还是清朝,到如今,王府早被推光光,贝勒爷、格格们都不知道跑哪里去了;同样的,你拿着中华民国的地契,来找我党要房子,那显然也是要不到。周星驰拿着明朝的尚方宝剑,要去砍清朝的官,显然也是搞笑。

    我们反正也管不了那么多了,能贷款,能付得起,那就买吧,这辈子反正要住的,反正租房子也是各种贵。买了房子,还可以自我陶醉下,觉得自己是一个千万富翁了。可以肯定的是,到最后,绝大多数的“千万富翁”都无法套现。如果房子人人最后都套现成功的话,都可以把美国买下来了。所以现在的情况下,无非是少量的成交,决定了房子的价格。

    对于绝大多数人来讲,房子真正对他起来的作用,其实最后客观上还是居住作用。如果目的就是居住,也不用想那么多了,买了。

     

     最后强调,我也是一个屌丝,以上是我作为一个屌丝,分享的一些我缓解焦虑的方法。对于文中的观点,相信大家还会有诸多的不同意,我以开放的态度,接受大家的批评与指正。

    查看更多精华文章,请扫描下发二维码关注LinuxDev:

    展开全文
  • 宋宝华:关于Ftrace的一个完整案例

    万次阅读 2018-01-24 23:49:39
    更多精华文章或者加入技术交流群请扫描下方二维码关注Linux阅码场 Ftrace简介 Ftrace是Linux进行代码级实践分析最有效的工具之一,比如我们进行一个系统调用,出来的时间过长,我们想知道时间花哪里去了,利用...

    更多精华文章或者加入技术交流群请扫描下方二维码关注Linux阅码场

    Ftrace简介

    Ftrace是Linux进行代码级实践分析最有效的工具之一,比如我们进行一个系统调用,出来的时间过长,我们想知道时间花哪里去了,利用Ftrace就可以追踪到一级级的时间分布。

    Ftrace案例

    写一个proc模块,包含一个proc的读和写的入口。test_proc_show()故意调用了一个kill_time()的函数,而kill_time()的函数,又调用了mdelay(2)和kill_moretime()的函数,该函数体内调用mdelay(2)。

    kill_time()的函数和kill_moretime()函数前面都加了noinline以避免被编译器inline优化掉。

     

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/version.h>
    #include <linux/proc_fs.h>
    #include <linux/seq_file.h>
    #include <linux/delay.h>
    #include <linux/uaccess.h>
    
    static unsigned int variable;
    static struct proc_dir_entry *test_dir, *test_entry;
    
    static noinline void kill_moretime(void)
    {
    mdelay(2);
    }
    static noinline void kill_time(void)
    {
    mdelay(2);
    kill_moretime();
    }
    
    static int test_proc_show(struct seq_file *seq, void *v)
    {
    unsigned int *ptr_var = seq->private;
    kill_time();
    seq_printf(seq, "%u\n", *ptr_var);
    return 0;
    }
    
    static ssize_t test_proc_write(struct file *file, const char __user *buffer,
    size_t count, loff_t *ppos)
    {
    ...
    }
    
    static int test_proc_open(struct inode *inode, struct file *file)
    {
    return single_open(file, test_proc_show, PDE_DATA(inode));
    }
    static const struct file_operations test_proc_fops =
    {
    .owner = THIS_MODULE,
    .open = test_proc_open,
    .read = seq_read,
    .write = test_proc_write,
    .llseek = seq_lseek,
    .release = single_release,
    };
    
    static __init int test_proc_init(void)
    {
    test_dir = proc_mkdir("test_dir", NULL);
    if (test_dir) {
    test_entry = proc_create_data("test_rw",0666, test_dir, &test_proc_fops, &variable);
    if (test_entry)
    return 0;
    }
    
    return -ENOMEM;
    }
    module_init(test_proc_init);
    static __exit void test_proc_cleanup(void)
    {
    remove_proc_entry("test_rw", test_dir);
    remove_proc_entry("test_dir", NULL);
    }
    module_exit(test_proc_cleanup);
    
    
    MODULE_AUTHOR("Barry Song <baohua@kernel.org>");
    MODULE_DESCRIPTION("proc exmaple");
    MODULE_LICENSE("GPL v2");

    模块对应的Makefile如下:

     

    KVERS = $(shell uname -r)
    
    # Kernel modules
    
    obj-m += proc.o
    
    # Specify flags for the module compilation.
    
    #EXTRA_CFLAGS=-g -O0
    
    build: kernel_modules
    kernel_modules:
     make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
    clean:
     make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

    编译并且加载:

     

    $ make

    baohua@baohua-perf:~/develop/training/debug/ftrace/proc$ 

    $ sudo insmod proc.ko

    [sudo] password for baohua: 

    之后/proc目录下/proc/test_dir/test_rw文件可被读写。

    下面我们用Ftrace来跟踪test_proc_show()这个函数。

    我们把启动ftrace的所有命令写到一个脚本function.sh里面:

     

    #!/bin/bash
    debugfs=/sys/kernel/debug
    echo nop > $debugfs/tracing/current_tracer
    echo 0 > $debugfs/tracing/tracing_on
    echo $$ > $debugfs/tracing/set_ftrace_pid
    echo function_graph > $debugfs/tracing/current_tracer
    #replace test_proc_show by your function name
    echo test_proc_show > $debugfs/tracing/set_graph_function
    echo 1 > $debugfs/tracing/tracing_on
    exec "$@"#replace test_proc_show by your function name
    echo test_proc_show > $debugfs/tracing/set_graph_function
    echo 1 > $debugfs/tracing/tracing_on
    exec "$@"

    然后用这个脚本去启动cat /proc/test_dir/test_rw,这样ftrace下面test_proc_show()函数就被trace了。

     

    # ./function.sh cat /proc/test_dir/test_rw

    0

    读取trace的结果:

    # cat /sys/kernel/debug/tracing/trace > 1

    接着用vim打开这个文件1,发现这个文件有600多行:

     

    天了撸,长到看不清!!

     

    Ftrace结果怎么读?

    Ftrace结果怎么读?答案非常简单:如果是叶子函数,就直接在这个函数的前面显示它占用的时间,如果是非叶子,要等到 }的时候,再显示时间,如下图:

    延迟比较大的部分,会有+、#等特殊标号:

     '$' - greater than 1 second
     '@' - greater than 100 milisecond
     '*' - greater than 10 milisecond
     '#' - greater than 1000 microsecond
     '!' - greater than 100 microsecond
     '+' - greater than 10 microsecond
     ' ' - less than or equal to 10 microsecond.

     

    vim对Ftrace进行折叠

    上面那个Ftrace文件太大了,大到看不清。我们可以用vim来折叠之,不过需要一个vim的特别配置,我把它存放在了我的~目录,名字叫.fungraph-vim:

    " Enable folding for ftrace function_graph traces.

    "

    " To use, :source this file while viewing a function_graph trace, or use vim's

    " -S option to load from the command-line together with a trace.  You can then

    " use the usual vim fold commands, such as "za", to open and close nested

    " functions.  While closed, a fold will show the total time taken for a call,

    " as would normally appear on the line with the closing brace.  Folded

    " functions will not include finish_task_switch(), so folding should remain

    " relatively sane even through a context switch.

    "

    " Note that this will almost certainly only work well with a

    " single-CPU trace (e.g. trace-cmd report --cpu 1).

     

    function! FunctionGraphFoldExpr(lnum)

      let line = getline(a:lnum)

      if line[-1:] == '{'

        if line =~ 'finish_task_switch() {$'

          return '>1'

        endif

        return 'a1'

      elseif line[-1:] == '}'

        return 's1'

      else

        return '='

      endif

    endfunction

     

    function! FunctionGraphFoldText()

      let s = split(getline(v:foldstart), '|', 1)

      if getline(v:foldend+1) =~ 'finish_task_switch() {$'

        let s[2] = ' task switch  '

      else

        let e = split(getline(v:foldend), '|', 1)

        let s[2] = e[2]

      endif

      return join(s, '|')

    endfunction

     

    setlocal foldexpr=FunctionGraphFoldExpr(v:lnum)

    setlocal foldtext=FunctionGraphFoldText()

    setlocal foldcolumn=12

    setlocal foldmethod=expr

    之后我们配置vim为这个模板来打开前面那个600多行的文件1:

     vim -S ~/.fungraph-vim 1

    这样我们看到的样子是:

    我们可以把光标移动到第5行,键盘敲打za,则展开为:

    继续展开第6行的kill_time(),按za:

    我们可以用z、a两个按键,搜索或者展开Ftrace的结果。

     

    最后,https://github.com/brendangregg/perf-tools对Ftrace的功能进行了很好的封装和集成,建议大家用perf-tools来使用Ftrace,则效果更佳更简单。

     

    有空再聊perf-tools。

    看完别忘了扫码关注"Linux阅码场"哦~

    展开全文
  • 更多精华文章请扫描下方二维码关注Linux阅码场 简介 火焰图(Flame Graph)是由Linux性能优化大师Brendan Gregg发明的,本文用最简单的实例讲解什么是火焰图,怎么画出来火焰图,火焰图的优点是什么。...
  • 宋宝华 DTS

    千次阅读 2015-08-07 21:21:46
    1. ARM Device Tree起源 Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”,引发ARM Linux社区的地震,随后ARM社区进行了一系列的重大修正。...
  • 名称空间是在OS之上实现容器与主机隔离,以及容器之间互相隔离的Linux内核核心技术。根据《Docker 最初的2小时(Docker从入门到入门)》一文,名称空间本质上就是在不同的工作组里面封官许愿。本文接下来从细节做一些...
  • 接着《Docker最初的2小时(Docker从入门到入门)》继续聊,再花10个小时写出《KVM最初的2小时(KVM从入门到入不了门)》。坦白讲,由于KVM远远比Docker要复杂,还是要2小时爱上KVM,这绝非难事,所以很可能入不了门...
  • 在下是一个码农,也号称是一个老湿,平生阅码农无数(吹牛的 ^-^)。经由大量的案例,我能够理解了为什么很多码农学了很多年Linux,还是感觉没有掌握要领,仍然内心崩溃,最终对Linux吐血而亡,正所谓:人世间最大的...
  • 共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这...
  • 僵尸不可能被杀死,因为它已经死了,不存在再死一次的问题。死的对立面是活,死者已死。只有活的进程才可能被杀死。什么是僵尸首先要明确一点,僵尸进程的含义是:子进程已经死了,但是父进程还没有wait它的一个中间...
  • 在《宋宝华:火焰图:全局视野的Linux性能剖析》一文中,我们主要看了on-cpu火焰图,理解了系统的CPU的走向的分析。但是,很多时候,单纯地看on-cpu的情况(什么代码在耗费CPU...
  • 本文解释linux内存中swappiness的作用,以及linux内存中swappiness=0究竟意味着什么。内存回收我们都知道,Linux一个进程使用的内存分为2种:file-backed pages(有文件背景的页面,比如代码段、比如read/write方法...
  • 宋宝华的blog

    2010-06-17 19:53:00
    http://blog.donews.com/21cnbao/
  • bcc是eBPF的一种前端,当然这个前端特别地简单好用。可以直接在python里面嵌入通过C语言写的BPF程序,并帮忙产生BPF bytecode和load进入kernel挂载kprob...
  • 有一次给一群码农演讲,我喷口水喷了快一个小时,说spinlock等的正确使用以及死锁的原因。下面有个人突然问,“老师,请问什么叫死锁?”。我心里想,把这个人拉出去枪毙一万...
  • 药不能停,直接进入正题,本文3分钟读完。文中涉及到的缩写如下:PID: 进程(process) IDPPID:父进程(parent process) IDPGID:进程组(process...
  • 宋宝华全部直播课程资料AND课件,注意!不是视频!是课件和资料,看好在下载。 课件内容包括总线设备驱动模型、设备树、进程调度,如有侵权,请联系我,我会及时删除
  • linux音频驱动详解--宋宝华

    热门讨论 2009-07-05 14:14:39
    主要介绍linux音频驱动,本文摘自宋宝华的《linux驱动详解》第十七章。不要积分的。
  • 打通Linux脉络系列:进程、线程和调度—1720人已学习 课程介绍 本课程分成4个组成部分,每次课60分钟,每次课后留下3-4个练习题,可以在Linuxer公众号留言讨论答案和做题心得。 第一部分:深入彻底搞清楚进程生命...
  • 宋宝华_精通LINUX设备驱动开发
  • 宋宝华网卡设备驱动

    2012-12-07 16:07:44
    刚刚看完《linux设备驱动_宋宝华》第十六章linux网络设备驱动。还是颇有感觉的。因前段时间又熟悉了一下TCPIP的相关常用协议的格式,再加上调试过arm2440上面的dm9000网卡的裸机驱动,再看设备驱动,恩,有感觉。...
  • linux驱动视屏教程-宋宝华13集,下载下来的是一个txt,里面是百度网盘的地址
  • 本文已首先在Linuxer公众号(ID: LinuxDev)发表,先转回我的blog也发表。转载请注明出处。 1.DMA ZONE的大小是16MB? 这个答案在32位X86计算机的条件下是成立的,但是在其他的绝大多数情况下都不成立。...
  • 宋宝华linux驱动详解资源百度云链接,链接永久有效,用于学linux编程驱动的IT技术员
  • 宋宝华视频讲解linux驱动开发,下载文件为百度网盘地址,输入密码获取视频
  • 宋宝华老师两天培训所得

    千次阅读 2015-11-06 10:09:40
    公司在11.1-11.2两天请来了宋宝华老师来为我们培训,虽然讲的都是基于C语言的有关Linux内核的知识,我还是在其中听到了一些同样适用于Java的常识技巧。 1.函数参数类型是boolean的,改为两个函数 我经常会写出一...
  • 宋宝华设备树视频的感想

    千次阅读 2017-11-27 14:11:36
    如果设备写在驱动里面,代码量非常大,而且非常不方便移植。因此将设备放在驱动外,再通过一个接口,和驱动关联,这个接口就叫做总线,在总线上挂载了设备了驱动。... 当匹配成功的时候,会进入probe函数。...

空空如也

1 2 3 4 5 ... 20
收藏数 18,527
精华内容 7,410
关键字:

groovy