写程序的时候,需要考虑理论上概率为零的意外情况吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Had Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
klxq15
V2EX    Python

写程序的时候,需要考虑理论上概率为零的意外情况吗?

  •  
  •   klxq15 2017-04-16 07:28:16 +08:00 via Android 7554 次点击
    这是一个创建于 3105 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如一个数值输入计算,要先判断它是否全为数字,然后再计算
    61 条回复    2017-04-18 17:04:26 +08:00
    340244120
        1
    340244120  
       2017-04-16 07:38:55 +08:00 via Android
    前端验证 and 后端框架验证(比如 struts 的 form validation)
    eyp82
        2
    eyp82  
       2017-04-16 07:48:25 +08:00   3
    如果理论上概率确实为 0, 那不需要考虑. 但是你确定是 0 吗?
    lcorange
        3
    lcorange  
       2017-04-16 07:48:36 +08:00
    java 不用, python 要用,避免猪队友硬传你个字符串"123"过来搞事情
    lucifer9
        4
    lucifer9  
       2017-04-16 08:01:57 +08:00   3
    概率为 0 的事件未必一定是不可能事件
    wenzichel
        5
    wenzichel  
       2017-04-16 08:07:13 +08:00
    你比如的情况,概率应该不是 0 吧。如果接收的输入情况较少,可以采用白名单的方式,比如只能数字类型才能通过;如果接收的输入情况较多,那么就用黑名单的方式,比如含有特殊字符不能通过
    mozutaba
        6
    mozutaba  
       2017-04-16 08:13:08 +08:00 via Android
    ' or 1 = 1'
    k9982874
        7
    k9982874  
       2017-04-16 08:19:57 +08:00 via iPad
    外部输入数据一概设定为不可信,严防 sb 用户和猪队友
    mcfog
        8
    mcfog  
       2017-04-16 08:30:03 +08:00 via Android
    正是因为概率是 0 ,所以要加断言来标清楚。”这里的输入老子就只处理数字,不爽不要玩“

    改这种风格代码非常爽,一改一跑一堆异常,解决完基本就没问题了
    kongkongyzt
        9
    kongkongyzt  
       2017-04-16 08:42:11 +08:00 via Android   1
    因为有猪队友的存在,所以一定要检验,亲身经历的事实。你永远无法想象你的队友有多蠢和粗心
    0TSH60F7J2rVkg8t
        10
    0TSH60F7J2rVkg8t  
       2017-04-16 08:45:06 +08:00
    概率为 0 的事情按常理说,你想都想不到;你能想到的,概率一定不为 0 。
    geelaw
        11
    geelaw  
       2017-04-16 08:45:58 +08:00   3
    因为计算机处理的内容是离散的,所以概率是 0 等同于不可能,不用处理。甚至小概率情况也不用管,比如硬件故障,这种完全管不了的情况也没法管。

    但是期待用户输入的东西,用户输入乱七八糟的内容还是很有可能的,譬如:

    - 用户输入了全角数字字符;
    - 用户输入小数点的时候输入成了句号;
    - 用户不小心在数字中间加了空格;
    - 用户使用了千位分隔符,而你以为大家都不用千位分隔符;
    - 用户使用 , 作为小数分隔符、使用 . 作为千位分隔符;
    - 用户误触键盘其他键但是忘了删掉或者手太快;
    - ……
    gamexg
        12
    gamexg  
       2017-04-16 08:50:02 +08:00 via Android
    python 类的?
    执行次类型转换,但是不需要自己处理异常。
    外部输入的参数有问题直接给他抛异常完事。
    Duolingo
        13
    Duolingo  
       2017-04-16 08:52:38 +08:00 via iPhone
    概率为 0 的事件不等于不可能事件……
    rogerchen
        14
    rogerchen  
       2017-04-16 09:01:43 +08:00 via Android   1
    要想模块化编程,必须把非法输入挡在函数的入口,多看代码大全
    wiselyv2
        15
    wiselyv2  
       2017-04-16 09:01:44 +08:00
    比如上次亚马逊 s3 服务器 down 掉,很多程序员就没处理这种情况
    codehz
        16
    codehz  
       2017-04-16 09:04:20 +08:00 via Android
    这个题目描述大概是有问题的,不过如果按照概率为 0 来理解的话,就是说假定用户都是专业用户,知道什么是未定义行为,输入内容保证符合要求。。。这种情况下,确实不需要考虑了
    as463419014
        17
    as463419014  
       2017-04-16 09:13:02 +08:00
    建议判断一下
    1.你永远不知道你的队友会如何坑你
    2.你永远不知道产品经理明天会不会改需求
    n6DD1A640
        18
    n6DD1A640  
       2017-04-16 09:16:16 +08:00
    永远不要相信外部的输入
    elfive
        19
    elfive  
       2017-04-16 09:17:47 +08:00
    工作认真对待该处理就处理;自己私下的小玩具就随意了。不过还是养成习惯最好。
    工作上,我一般直接给 return ;
    私下的朋友间的玩具,一般都是:
    print("搞事啊!!");
    exit(1)
    #滑稽
    cy18
        20
    cy18  
       2017-04-16 09:25:05 +08:00 via Android
    理论概率为零就抛异常或者 assert 呗
    unoyx
        21
    unoyx  
       2017-04-16 09:38:36 +08:00
    不是很理解你这个理论上为 0 ……
    放在实际开发中,确实是能想到的错误出现的概率都不见得为 0 。即使是内存 bit 读写会翻转,这种问题放到一些环境下也是需要进行处理的。
    所以实际上开发中的错误一般是依据出现的上下文,可能产生的影响,或者说是各种处理方案的性价比来决定处理方案。
    具体到你的例子,如果这个处理放在用户输入部分。即使你事先准备了各种提醒,那也架不住用户一不小心做了错误的输入。而且这种时候你不做处理那么程序可能会 crash ,用户体验会非常糟糕,那么最好是预先阻止掉各种意外的输入。如果你的处理只是一个内部调用的子函数,而且你已经和调用方约定好了输入只能是数字,那么再出现问题一般就是由调用方进行处理了。
    Cbdy
        22
    Cbdy  
       2017-04-16 09:45:27 +08:00 via Android
    断言就是这个时候用的
    cwlmxwb
        23
    cwlmxwb  
       2017-04-16 10:03:55 +08:00 via iPhone
    @lucifer9 此话怎讲
    GlobalNPC
        24
    GlobalNPC  
       2017-04-16 10:06:26 +08:00
    @lcorange 哈哈哈。
    sagaxu
        25
    sagaxu  
       2017-04-16 10:11:17 +08:00 via Android
    用户输入,任何情况下都要检查。 API 调用,契约式编程无需检查,防御式编程要检查。
    vincentqi
        26
    vincentqi  
       2017-04-16 10:21:58 +08:00
    曾经有一个产品经理的用户名是 null
    Phariel
        27
    Phariel  
       2017-04-16 10:23:42 +08:00 via Android
    墨菲定律 有几率会发生的事情一定会出错 并且人类认为零概率的东西通常都有概率发生
    wly19960911
        28
    wly19960911  
       2017-04-16 10:23:56 +08:00 via Android
    就算前端可以帮你挡住,假如有人要发包测试呢,这东西没有 0%的,如果不涉及数据库和业务的话我懒得检测,涉及的话该怎么样就怎么样
    bukip
        29
    bukip  
       2017-04-16 10:49:30 +08:00
    “比如一个数值输入计算,要先判断它是否全为数字”

    这种可能性远远大于 0
    iyaozhen
        30
    iyaozhen  
       2017-04-16 10:54:27 +08:00 via Android
    你举得例子和你的标题不符呀。
    编程法则:不要信任任何用户输入

    但比如说你是强类型语言申明了输入类型或者框架上做了处理,这种业务代码上就不用判断了
    gamexg
        31
    gamexg  
       2017-04-16 11:16:10 +08:00
    我的做法:

    用户输入类的,需要检查并给出友好提示。

    如果是其他函数调用提供的参数,那么做一次强制转换,失败了不管,异常直接抛出去,由调用方处理。

    如果是类似 t/355154 里面的 355154 ,理论合法用户不会出现非数字的情况,这种直接同函数调用,直接抛异常。但是别忘了设置整站的 500 页面及错误日志。
    jayzjj000
        32
    jayzjj000  
       2017-04-16 12:32:48 +08:00
    作为开放出去的公用库,只要不是强类型,都建议判断

    另外,另一种思路是如果产生了这种异常分支,不处理这个分支对整个工程的影响,拿正文举例:
    - 如果不处理的结果是输出不满足输入结果需要,那么可以不处理,因为输入结果就是错误的
    - 如果不处理的结果是抛异常或者 Crash ,那么再怎么样都要处理,防止出现“你这个函数写的容错性怎么这么差”的攻击机会
    Khlieb
        33
    Khlieb  
       2017-04-16 12:35:00 +08:00 via Android
    这就需要采取边界检查的机制
    wanttofly
        34
    wanttofly  
       2017-04-16 12:44:10 +08:00
    哎,其实最悲剧的是你写程序考虑了很多低概率事件,设想了很多极端的情况,却发现一个用户都没有操作到那种情况简直想死,哦,因为没人用。哈哈!
    phrack
        35
    phrack  
       2017-04-16 12:46:44 +08:00 via Android
    never trust any input
    anuan
        36
    anuan  
       2017-04-16 13:25:04 +08:00
    先跑起来再说别的
    lc4t
        37
    lc4t  
       2017-04-16 13:26:29 +08:00
    射飞镖的时候射中盘上任意一点概率都是 0 ,因为点 /面=0 ,但是只要射中了概率为 0 的事情就发生了,所以概率为 0 不是不可能发生。

    对于用户的输入,即便用户完全不可能输入一个值,也要防止测试给你一个意外输入。总之原则上就是考虑所有可能。
    viator42
        38
    viator42  
       2017-04-16 13:31:17 +08:00 via Android
    我觉得能做的验证还是尽量做,一方面防那些搞事情的,另一方面减少出一些奇怪的 bug 。墨菲定律不信不行啊
    crist
        39
    crist  
       2017-04-16 13:33:13 +08:00
    为 0 你考虑个卵!
    kaneg
        40
    kaneg  
       2017-04-16 14:16:05 +08:00 via iPhone
    如果真的概率很低,比如 CPU 的逻辑门被宇宙射线改变了电平,是可以不用考虑。可问题你提的用户输入是否数字,这个出错的概率太高了,起码有 2 , 3 成。
    zyEros
        41
    zyEros  
       2017-04-16 14:17:54 +08:00 via iPhone
    这种情况就需要学习一下防御性编程,因为概率为 0 ,除非你可以证明得到
    jason19659
        42
    jason19659  
       2017-04-16 14:48:54 +08:00
    首先要论证是不是真的概率为 0
    bombless
        43
    bombless  
       2017-04-16 14:59:49 +08:00 via Android
    看过一个说法,说过马路总是记得往马路两头看的人才是合格的程序员。起码这个说法还是挺有趣的,哈哈
    klxq15
        44
    klxq15  
    OP
       2017-04-16 15:02:43 +08:00 via Android
    这样啊,看了大家的评论感觉还是加上判断好一些,谢谢大家的回复~
    watcher
        45
    watcher  
       2017-04-16 15:05:27 +08:00
    多写两行 穷不了你 富不了我... 写不出吃亏 写不出上当...
    realpg
        46
    realpg  
    PRO
       2017-04-16 15:09:45 +08:00
    不相信任何其他途径传过来的数据
    reus
        47
    reus  
       2017-04-16 15:19:26 +08:00
    如果你要这样做,那就别用 python 了,用静态类型语言。
    nicevar
        48
    nicevar  
       2017-04-16 16:14:48 +08:00
    保证程序的健壮性是很有必要的,因为你想不到的情况太多了
    很多年前刚参加工作在一公司,软件发布前经过整个部门的轮番测试觉得已经不错了然后就发出去,结果短短几天用户反馈的 bug 达到 200 多个,当时测试跑过来说这个事我就惊呆了
    loading
        49
    loading  
       2017-04-16 16:47:18 +08:00 via Android
    不要相信提交的任何内容,不是基本原则吗?
    atnopc
        50
    atnopc  
       2017-04-16 16:56:41 +08:00
    之前有个和本地 zf 合作的一个项目
    用户群是中老年人
    你就会发现你认为这个概率为 0 的想法有多么不靠谱了
    AstroProfundis
        51
    AstroProfundis  
       2017-04-16 20:17:30 +08:00
    用户输入不符合预期的数据这种事情概率不应该是接近 1 的吗,楼主怎么会产生概率为 0 的错觉
    blessyou
        52
    blessyou  
       2017-04-16 20:34:54 +08:00 via iPhone
    考虑过服务器挂掉 1988 次,然后突然觉得,哼 怎么可能,不存在的
    si
        53
    si  
       2017-04-16 20:45:58 +08:00
    接近零!=零,即使概率再小他也不为零。不为零就是肯定会发生。为零是肯定不会发生。
    Mutoo
        54
    Mutoo  
       2017-04-16 21:10:47 +08:00
    莫非定律, Anything that can go wrong, will go wrong.
    https://zh.wikipedia.org/wiki/%E6%91%A9%E8%8F%B2%E5%AE%9A%E7%90%86
    lifanxi
        55
    lifanxi  
       2017-04-16 21:50:39 +08:00
    37 楼说得对,概率为 0 并不表示不发生,所以不能一概而论要不要处理“概率为 0 ”的情况,最多只能讨论“不会发生的事件”要不要处理。
    BOYPT
        56
    BOYPT  
       2017-04-16 21:52:30 +08:00
    if(false) { alert("something happeded ... "); }
    ra1983
        57
    ra1983  
       2017-04-16 21:53:55 +08:00 via Android
    @bombless 我看到的说法是过单行道也看两边的程序员,哈哈
    jatesun
        58
    jatesun  
       2017-04-17 08:51:20 +08:00
    当然啦,你要问我考不考虑我说考虑,我就可以明确的告诉你
    pepesii
        59
    pepesii  
       2017-04-17 09:04:30 +08:00 via iPhone
    为啥我想起了人生三大错觉
    kuber
        60
    kuber  
       2017-04-17 13:32:57 +08:00
    曾经碰到一个奇葩的 bug ,一个 button 点 10 次以上程序会崩溃。特别佩服那个测试。
    ryanzyy
        61
    ryanzyy  
       2017-04-18 17:04:26 +08:00
    你的情况需要详细了解你所说的数值输入是什么
    如果来源为 Web Form ,用户用第三方软件生成的文件之类的 那么必定要验证
    如果来源为 自己另一处的代码 可以考虑加一个 验证 然后直接报 Runtime Error (提醒自己用的) 或者也可省略

    你说的理论概率为 0 是不需要写代码做额外处理的
    比如
    do
    uuid = UUID.generate_new_uuid
    end while existing_uuids[uuid]
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5894 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 02:20 PVG 10:20 LAX 19:20 JFK 22:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86