编写程序很难吗?

发布网友 发布时间:2022-04-24 12:48

我来回答

7个回答

懂视网 时间:2022-05-08 00:37

前言

写程序有时候真的有点难,要考虑各种情况。

应用在运行中,会不断生成日志文件。假如要实现一个日志收集的工具,不考虑其它的分析功能,只考虑收集,有哪些方面要考虑的?

首先看下一般的log框架是如何输出日志的:

可能是这样的:a.log.1, a.log.2, a.log.3, a.log.4, a.log.5 循环输出;

可能是这样的: a.2014-5-5.log, a.2014-5-6.log, a.2014-5-7.log,每天生成一个日志文件;

可能是这样的:log.out,每次重启都会生成一个新的log.out,覆盖旧的文件。

那么,我们有哪些方面要实现和注意的?

  • 提供正则或者globs方式的通配符。
  • 要能判断文件是不是新建的。
  • 如何判断文件有没有更新?
  • 如何保存文件的读取进度?
  • 如果我们在读取文件的过程中,文件被删除了会怎样?
  • 如果我们在读取文件过程中,进程挂了,读取进度有没有及时保存?
  • 在保存文件进度时,如果挂了,重启能不能正确恢复文件进度?
  • 能不能保证读取的内容不重复?
  • 如果日志文件很快生成,又很快删除了,是否能保证不漏掉?
  • 如果日志文件是软链接(soft link),能不能正确处理?
  • 文件系统的inode会被回收利用,能不能处理这个?
  • 有没有控制读进内存的数据的大小,防止占用过多的内存?
  • logstash的实现

    下面解释下logstash是如何实现和处理上面的问题的:

    可以配置path参数(Array),其中支持globs风格的匹配,如:

    path => [ "/var/log/messages", "/var/log/*.log" ]

    可以配置exclude参数(Array),排除掉不需要的文件,如:

    exclude => "*.gz"

    利用inode来识别新文件

    logstash把进度保存到所谓的sincedb里,实际上即这样的一个文本文件,默认是放在home目录下的,如:

    .sincedb_e794081d6134aace51b759aea8cc3be2

    .sincedb_f7a0c8a0def03e0c572511ceea0b9f63

    后面是日志文件,即path的hash值。这样就区分了不同的文件名的日志文件的进度保存问题。

    sincedb文件里是类似这样的内容:

    6511055 0 2051 118617881
    5495516 0 2051 155859036
    63413 0 2051 148511449

    上面的4列分别是:

    inode, major number, minor number, pos。

    其中major number和minor number是设备相关的数字,参考:http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers

    inode是文件系统给文件分配的是一个号码,参考:http://zh.wikipedia.org/wiki/Inode

    因此logstash区分了设备,文件名,文件的不同版本。

    这里引出了一个新问题,用inode来判断文件的不同版本,是否够准确了?因为inode是会回收再使用的。

    比如依次执行下面的命令,可以发现,两个文件的inode是一样的:

    touch teststat testrm test touch teststat test

    但是因为logstash是没有close掉文件,所以是一直持有inode,所以新的同名的日志文件会有一个新的inode。

    也正是因为这样,如果logstash监视的日志文件如果被删除了,还是可以继续把删除的文件的内容处理完。

    利用inode这点特性,有时可以做一些补救工作,比如不小心把mysql的文件删掉了,还是可以把数据dump出来,因为mysql进程还持有数据文件的inode。

    另外,logstash默认是每隔1秒就尝试读取文件有没有新内容,默认是15秒就扫描,检查有没有新文件。对应stat_interval和discover_interval参数。

    还有一些小细节:

    比如每次最多只读取出16394字节的数据,防止占用过多的内存,每5秒判断下是否需要保存新的pos。

    如果日志文件被删除了,也会删除sincedb文件。

    利用rename原子性地保存pos

    当读取到新文件内容时,pos会增加,在保存新的pos到sincedb时,logstash采用了临时文件的办法:

    先建立一个临时文件,写入新内容,再调用操作系统提供的remane函数,原子性地替换原来的sincedb文件。

    这种实际上是比较常用的技巧了,redis也是这样子做的。

    能否保证不重复,不丢失数据?

    很遗憾,这是不能的,除非是分布式事务,否则,总有可能丢失或者重复发送数据。任何日志收集软件或者消息队列软件都是如此。

    实现的代码

    具体的实现代码就不贴了,因为比较易读,其中logstash使用了filewatch这个库,可以用gem来安装。相关的代码在线查看:

    https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb

    https://github.com/jordansissel/ruby-filewatch/tree/master/lib/filewatch

    和fluentd的in_tail插件比较

    fluentd也是一个很流行的日志收集工具。

    简单再看了下fluentd的in_tail插件,发现里面还有自己当年提交的一个防止内存占用过大的建议:)

    https://github.com/fluent/fluentd/blob/master/lib/fluent/plugin/in_tail.rb

    iflines.size>=MAX_LINES_AT_ONCE

    # not to use too much memory in case the file is very large

    read_more=true

    即每最多读取1000行,就提交数据,并保存pos。

    fluentd的in_tail插件的原理和logstash的file input是差不多的,都是用inode来区分文件是否更新。

    但是fluentd只保存了inode和pos,没有logstash那样把设备都考虑进去了。

    另外fluentd保存pos时,都是以文件追加的方式来保存的,没有像logstash那样是用rename文件来保存到新文件里。显然logstash的实现更加合理。

    扯远一点,logstash部署要比fluentd方便,尽管两者都是用ruby写的,不同的是logstash默认是jruby,只要有JVM就可以跑,fluentd则要安装ruby环境,比较麻烦。

    其它的一些东东:

    logstash大有一统江湖之势,这句话忘记在哪里看到的了。在github上的logstash的start有2000多个。

    logstash + elasticsearch + Kibana的日志收集,搜索,展现的一条龙服务非常流行。

    参考:

    http://unix.stackexchange.com/questions/73988/linux-major-and-minor-device-numbers

    http://zh.wikipedia.org/wiki/Inode

    https://github.com/elasticsearch/logstash/blob/v1.4.1/lib/logstash/inputs/file.rb

    热心网友 时间:2022-05-07 21:45

    很难,尤其是对中国人
    精通一门编程语言需要10-20年,而很多的编程语言本身设计的局限性比较大,或者过于复杂,导致学编程的人根本没法完全的掌握。
    编程的难点,
    1 英文字母,这个很致命,因为我们看中文是从小看,可以做到一目十行,但是看英文,我们的阅读水平明显下降。这样很影响我们对于代码的理解和编程速度。
    2 标点符号的过分使用,英语对于标点的热爱远超中文,导致我们在编程中不得不频繁的切换。

    3 思维逻辑的西方化,编程语言都是西方人设计的,所以思维逻辑上符合西方人的理解方式
    中国人的思维逻辑和他们完全不同
    4 编程语言普遍太老,目前的最流行的几十种编程语言的出生时间,最年轻的GO(谷歌的)也有10年了,设计思想,语言习惯等等,都有明显的时代特征,很多的设计理念,思想,语法结构都显得多余。
    综上,编程语言本身的问题太多,导致了中国人学习起来困难。

    热心网友 时间:2022-05-07 23:03

    把写程序说的比登天还难?我只能呵呵了,其实只要走对路,写代码比吃饭还简单,当然要有10年的积累。比如银行系统,各种物联网设备等。如果专研一个行业的系统,很久,我跟你说,就是小学学历,都能比外面的博士都强!应为他们如果也要搞你这个行业,也会碰到同样的坑,也需要时间积累的。特别是一些需要大量实验后得出的独特算法。没有做过实验就想出结果是不可能的。再说说技术升级,并不是所有技术都要去学的,就算穷尽你一生都不可能学完。只要把目前你研究的行业的需要的技术学一下就行了。而且目前很多都不需要你写了,程序员最反对重复造轮子,直接拿别人的用就行了。当然前提是你得看得懂。当你有10年以上工作经验后你会发现,你已经有一个(军火库)了,常用代码库,这和刚毕业的大学生可是有天壤之别的。在开发项目时你可以一跃千里,根本不用重头开发。而且到这个级别了,其实完全可以找两个徒弟帮你写,你自己写核心代码。这样不要说30岁,50岁我觉得可能还有战斗力。只要有算法,其他都是浮云,哪怕你不会新语言,但是你有算法,一样吃的开。

    热心网友 时间:2022-05-08 00:38

    编程难不难?那可不是闹着玩的。不从事这一行的永远不知道这行的艰辛,还咋巴着小眼睛问编程好不好学?
    不知道LZ看没看过圣斗士星矢这部动漫,如果你想踏入编程殿堂,就要先想想那个被无数小孩子嘲笑的实力很菜又只会死缠滥打经常*得体无完肤的主角星矢,嘲笑归嘲笑,但是你遇到的问题跟星矢差不多。许许多多难以解决的问题,像一座座大山一样压迫着你,而且你找不到人问,无从下手。但是你比星矢好点,星矢战胜不了敌人生命就会终结,你解决不了问题可能永远的就半途而废于编程无缘了。所以学编程前,首先你得问问自己,想学编程,你有没有像星矢一样持之以恒百折不挠一步一个脚印忍受常人无法想象的困难和痛苦的品质,没有?你说我开玩笑逗你,那好,下面的不用看了,应该你确实不适合学。
    如果你只想着挣大钱,劝你别碰这行,一句话,别来找虐。为什么?你看到的手机APP,各种应用,要想开发出来,不知道需要多少种技术。拿最常见的网站开发,需要后台数据库mysql,数据格式json,xml,各种网络协议,还有网站开发语言PHP, JSP,ASP.NET,等等不下十几种技术。而每一种技术都是一本厚厚的五六百页的书,需要最少一年多时间掌握一门技术。最要命的,每种技术互不交叉还跨度很大,每种技术都有自己的设计理念和很多很多“天坑”在等着你攻克,你问问你自己,你有这个恒心和意志力天天捧着本大部头的书天天看,天天上机操作学吗?你说有,那好,你看电视上那些富二代天天潇洒地到处游玩泡妞基本于你无缘了,因为你根本就没时间,谈个恋爱都困难,还想打网游玩王者?那算了,你还是别碰这行了,别耽误你玩游戏享受生活了。
    程序员加班很恐怖,工作制通常是996,即早9晚9周六还要上班,晚9下班还是早的,一般到晚上十点。你想那时夜深人静了人家都休息抱着老婆睡觉了,你还在工作中,是不是很崩溃?
    第2,程序员耗脑太严重。工作中需要十几个小时大脑不停地运转。需要设计算法,不断地把代码改来改去来适应客户一天几变的需求。很多功能没有现成的解决方案,还经常遇到一些天书一样的疑难问题,bug,实际工作中突发状况千奇百怪,你可能见都没见过的bug,崩溃,需要一点一点查几万行的log日志。而且也需要百度,google,英文论坛寻求帮助,理解错误信息是什么意思。所以英文不好的没耐心的还是算了吧,不适合这行。
    第3. 程序开发首先是非常难学的,任何一门编程语言都有自己独到的思想,概念设计,很多情况下一门语言与另一门语言没有多大关系,知识经验无法串用。当然好多大牛说什么编程思想是互通的掌握核心算法思想就行了但是我编程开发这么多年实在看不出有多少互通,学好一门能一通百通?骗骗小孩子还差不多。一门语言与另一门差太远了好不?工作中你用到这些技术你还不得不去学。而且程序技术日新月异,新类库新SDK每天都会推出,你需要日复一日不断地学习新技术。如最新视频解码技术,游戏引擎等等,而这些新技术可是国内没有书和任何资料的,需要你到英文官方网站去找实例看文档去学,更要命的,新的技术和老的还没太大关联,你得重头去学。而且老板急赶项目不会给你什么时间,一般三天就是极限了,你需要这么短的时间快速掌握一项新技术...
    综上,你明白程序员为什么总要加班了吧,也知道这行不是人干的吧。为什么说程序员干到三十干不动。很简单,以这种消磨人生所有时间状态,你生命中只有加班加班工作工作学习学习,你将不能顾家不能跟朋友聚会不能再有自己一点点休闲时间,更别说谈女朋友恋爱了,以这种状态你能坚持到三十岁?我想那简直是个奇迹了

    热心网友 时间:2022-05-08 02:29

    写程序说简单就简单,说难就难,为什么呢?说简单,是因为程序的执行都是死的,一样的代码不会出现两个结果,程序不会说谎。说难,是因为程序考研的事你解决问题的逻辑能力,必须要严谨,哪怕你一个小小的疏忽可能都会造成整个程序的不可用。 具体如何写,那要取决于你想学习哪门计算机语言。具体写法都会有一些不同,但是主要的编程思想都是一样的,计算机语言之间都是换汤不换药。如果你没学过写程序,即使我在这里告诉你怎么写,估计你也不会理解,如果有兴趣,不如自己亲自体验一下。

    热心网友 时间:2022-05-08 04:37

    也不一定,要看什么程序

    热心网友 时间:2022-05-08 07:02

    你是做数控的吗

    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com