V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qwe3364925
V2EX  ›  PHP

给 phper 出一道基本的面试题, 做错了得加强基础了/

  •  1
     
  •   qwe3364925 · 2017-03-23 16:11:43 +08:00 · 7417 次点击
    这是一个创建于 2588 天前的主题,其中的信息可能已经有所发展或是发生改变。
    请输出该结果
    echo '6+5' . 9+7;
    74 条回复    2017-03-26 22:36:32 +08:00
    hiboshi
        1
    hiboshi  
       2017-03-23 16:15:05 +08:00
    6+516
    不知道对不对
    hiboshi
        2
    hiboshi  
       2017-03-23 16:15:55 +08:00
    @hiboshi 面壁去了
    wdd2007
        3
    wdd2007  
       2017-03-23 16:16:05 +08:00
    13
    Immortal
        4
    Immortal  
       2017-03-23 16:30:36 +08:00
    126 么- -
    holyghost
        5
    holyghost  
       2017-03-23 16:33:18 +08:00
    你离挨喷还有三十米。
    silencefent
        6
    silencefent  
       2017-03-23 16:36:18 +08:00
    不懂为什么是 13 ,能解释下吗?
    sxycodecat
        7
    sxycodecat  
       2017-03-23 16:36:27 +08:00
    13 实际 计算为 6+7
    和 “ 123abc ” +1 输出结果为 int 124 一个性质
    qwe3364925
        8
    qwe3364925  
    OP
       2017-03-23 16:37:56 +08:00
    @sxycodecat 那么快揭晓答案 , 没意思啦, 我就像看看有多少人会做错
    gino86
        9
    gino86  
       2017-03-23 16:38:02 +08:00
    这道题考的应该是运算符的优先级和类型的转换的吧,然而我做错了。
    sxycodecat
        10
    sxycodecat  
       2017-03-23 16:38:50 +08:00
    @silencefent 字符串类型和数值类型 做运算 只能取到 第一个非数字字符串前的数字进行计算 如果是 “ a6+5 ”.9+7 结果就变成 7 了。
    sxycodecat
        11
    sxycodecat  
       2017-03-23 16:39:30 +08:00
    @qwe3364925 啊哈哈哈 能删吗。 ( ⊙ o ⊙ )!
    sxycodecat
        12
    sxycodecat  
       2017-03-23 16:44:37 +08:00
    @qwe3364925 你把加法换成乘除 又得错一批。 哈哈哈。
    silencefent
        13
    silencefent  
       2017-03-23 16:44:50 +08:00   ❤️ 3
    @sxycodecat 也就是说
    echo '6+5' . 9+7
    // ‘ 6+59 ’+7=6+7=13
    sxycodecat
        14
    sxycodecat  
       2017-03-23 16:48:12 +08:00
    @silencefent 对头。 不过就加减法 有用。 乘除法输出的结果 又不一样 优先级的问题。
    KIDJourney
        15
    KIDJourney  
       2017-03-23 16:51:25 +08:00   ❤️ 12
    为什么有人会写这种屎一样的代码呢?
    SoulGem
        16
    SoulGem  
       2017-03-23 16:53:21 +08:00
    ..捂脸
    darluc
        17
    darluc  
       2017-03-23 16:57:49 +08:00
    服!
    akira
        18
    akira  
       2017-03-23 16:58:59 +08:00
    echo '6+5' . (9+7)
    echo '6+5' . 9*7

    +-. 这 3 个运算符就不该设定为同一优先级。字符串连接符的优先级设置到最低的话,少好多事情
    changwei
        19
    changwei  
       2017-03-23 17:16:50 +08:00 via Android   ❤️ 8
    现在这种面试题都喜欢考歪门邪道的代码写法。看看 c prime plus 之类的书籍会有考 i+++++i 等于多少之类的习题吗?

    碰到代码可能出现结果歧义的坑尽可能用 intval , strval 解决,碰到可能出现优先级歧义的坑用括号括起来这些都是国外很多优秀书籍会强调的地方。而不是写这种含糊不清的代码然后作为坑留给下一个接手的人。
    mysterin
        20
    mysterin  
       2017-03-23 17:59:53 +08:00   ❤️ 2
    你知道“茴”字有多少种写法吗?
    不知道,反正用不上。
    littleylv
        21
    littleylv  
       2017-03-23 18:03:41 +08:00
    我觉得出类似的这种题最为笔试题的都是 213
    谁特么会写这么烂代码
    TIGERB
        22
    TIGERB  
       2017-03-23 18:06:30 +08:00   ❤️ 6
    解: '6+5' . 9+7

    知识点:
    1. 运算符优先级:这里“. +”运算符的优先级一样,所以从左到右依次运算
    2. 字符串做算数运算,字符串会从左到右开始直到不是数字的字符为止转为 int 类型进行算术运算

    step 1: '6+5' . 9 => '6+59'
    step 2: '6+59' + 7 => 6 + 7 => 13
    haiyang416
        23
    haiyang416  
       2017-03-23 18:33:14 +08:00
    然后回答正确,哈哈。
    misaka20038numbe
        24
    misaka20038numbe  
       2017-03-23 18:35:40 +08:00
    我觉得这个语句就应该直接报错, ERROR :代码出错啦,字符串不能加数字!
    lepig
        25
    lepig  
       2017-03-23 18:41:34 +08:00   ❤️ 1
    看到这样的面试题不应该是扭头就走吗? --引用一位 V 友的话
    lepig
        26
    lepig  
       2017-03-23 18:43:45 +08:00   ❤️ 1
    还要说一句,这样的代码真的是反人类的代码。不过我还是默默的弄清楚原理吧...溜
    quericy
        27
    quericy  
       2017-03-23 18:59:01 +08:00
    虽然知道考的是运算符优先级的问题,但还是做错了= =

    其实每次遇到这种题的时候都很纠结:
    一边想吐槽实际项目敢写这种代码的肯定在 review 的时候会被打死;
    一边也想所谓的知己知彼,弄清楚原理自己遇到才不会踩坑;

    然而踩得坑多了很多时候也只是记起来“哦,这一块有坑”,遇到的时候还是会手动求证一下...

    或许这也是这类题目总是会被喷又不断有人出的原因?
    crab
        28
    crab  
       2017-03-23 19:19:18 +08:00
    这种代码和 i=++i++i++i++ 一样吧?
    sunsh217
        29
    sunsh217  
       2017-03-23 19:22:43 +08:00
    出这种题的,必然是傻逼喽。
    zingl
        30
    zingl  
       2017-03-23 20:44:16 +08:00   ❤️ 1
    括号键坏了?
    motecshine
        31
    motecshine  
       2017-03-23 20:46:34 +08:00 via Android
    这种奇技淫巧弄出来是找喷的
    mcfog
        32
    mcfog  
       2017-03-23 21:45:09 +08:00 via Android
    面试官就算不是公司技术水平最高的人,至少也是核心骨干吧,出这种面试题的公司我选择筛掉它,要么连面试的目的都不知道,要么什么是真正的基础搞不清楚
    sagaxu
        33
    sagaxu  
       2017-03-23 21:49:08 +08:00
    哪个 sb 公司出这种题,扭头就跑
    cxbig
        34
    cxbig  
       2017-03-23 21:49:42 +08:00
    考校这种东西有意义么?工作中有谁会这么写逻辑。。。
    wdlth
        35
    wdlth  
       2017-03-23 22:05:29 +08:00
    那为何不问 echo '6+5' . 9+7 和 echo '6+5'.9+7 及 echo '6+5' .9 + 7 的区别?
    moult
        36
    moult  
       2017-03-23 22:05:34 +08:00
    intval('123abc')===123 !!!
    跟 JS 的 parseInt 返回一样的。
    realpg
        37
    realpg  
       2017-03-23 22:08:02 +08:00
    出这题的,中谭浩强的毒太深 没救了 直接拉太平间火化了吧
    dangyuluo
        38
    dangyuluo  
       2017-03-23 22:26:15 +08:00
    茴字的六种写法,你会么?
    allenhu
        39
    allenhu  
       2017-03-23 22:51:05 +08:00   ❤️ 1
    没任何意义,写出这样的代码,基本也不用混了🙅
    bianhua
        40
    bianhua  
       2017-03-23 23:10:13 +08:00   ❤️ 2
    @realpg

    不觉得。

    我倒是觉得这原因是 PHP 花样坑人,因为这里在拼接字符串的时候又引入了 PHP 自动类型转换的规则。而 PHP 的转换规则很多时候就是在造坑。

    比如例子里的 ((int)'6+1') == intval('6+1') == 6 。从其他语言的叫都上来看完全属于设计不合理,因为会导致混乱。

    试想如果你想严格判断整数输入的话,只能在 intval 转换前再加上一些格式判断,否则甚至可能就会导致安全问题(比如 var_dump('0e1' == '0e2') => true )。

    在语言这么坑的情况下,想写出安全稳定的程序真是如履薄冰。
    rashawn
        41
    rashawn  
       2017-03-23 23:24:25 +08:00 via iPhone
    楼主是来黑最好语言的吧
    realpg
        42
    realpg  
       2017-03-24 00:23:10 +08:00
    @bianhua #40
    就运算符优先级这种问题来说,合格的 PHPer 的套路是 不去管它优先级,显而易见的加法乘法不算,其他能括号就括号,能拆开写就不连一起写 没必要炫技 就算你现在写的优先级对,万一哪天 PHP 大升级调整优先级规则 那之前历史代码全得一点点改
    wohenyingyu02
        43
    wohenyingyu02  
       2017-03-24 00:26:27 +08:00
    看不懂
    des
        44
    des  
       2017-03-24 08:15:04 +08:00
    @qwe3364925 来来来,楼主请答一下这题
    class A{
    public $bar = 1;
    public $c = 2;
    }
    $a = new A();
    $bar = ['baz'=>'c'];
    echo $a->$bar['baz'];

    @moult
    js 嘛,坑多了去了
    比如这个
    if([]){alert(0);};
    if([]==false){alert(1);};
    if(![]==false){alert(2);};
    killerv
        45
    killerv  
       2017-03-24 08:57:56 +08:00
    没有意义,写这种代码的人会被打死
    Clarencep
        46
    Clarencep  
       2017-03-24 09:12:55 +08:00
    看到 LZ 被喷我就放心了 -- 加个括号会死啊!
    qdpoboy
        47
    qdpoboy  
       2017-03-24 09:31:12 +08:00
    @TIGERB 走对第一步,却走错了第二部,是不是要重新回炉下基础知识 /苦笑
    mx1700
        48
    mx1700  
       2017-03-24 09:38:50 +08:00 via Android
    看到楼主被喷我就放心了
    cjyang1128
        49
    cjyang1128  
       2017-03-24 09:55:04 +08:00
    这种题目的意义不在于程序员为什么会写出这种代码,而在于 phper 要关注代码的安全性。如果大家做过 web 渗透或者代码审计的话,就不会喷了,因为很多情况下可以通过这种强制类型转换绕过一些判断。
    CuminLo
        50
    CuminLo  
       2017-03-24 10:20:02 +08:00
    @Immortal 然后就没有人接你这个话了。

    ```
    php -r 'echo '6+5' . 9+7 . PHP_EOL;';
    126
    ```
    2owe
        51
    2owe  
       2017-03-24 10:33:55 +08:00
    有几种情况:

    1. 126

    php -r 'echo '6+5' . 9 + 7;'

    相当于 intval('11' . '9') + 7


    2. 13

    php -r "echo '6+5' . 9 + 7;"

    相当于 '6+59' + 7 = 6 + 7 ,运行会报警 Notice: A non well formed numeric value encountered ,说明有碰到这种非预期的数值转化,可能有 bug 。


    3. syntax error

    php -r "echo '6+5'.9 + 7;"

    报错 PHP Parse error: syntax error, unexpected '.9' (T_DNUMBER), expecting ',' or ';' in Command line code on line 1
    『.9 』 被当成符号了, echo 后面只支持 『,』和『;』。
    CuminLo
        52
    CuminLo  
       2017-03-24 10:37:22 +08:00
    @2owe 赞。
    mentalidade
        53
    mentalidade  
       2017-03-24 10:53:20 +08:00
    @2owe 第一种情况,单引号里面内容是不会被解释的,肯定错了
    suren1986
        54
    suren1986  
       2017-03-24 11:10:18 +08:00
    为什么要写这样的代码?炫技?
    allenhu
        55
    allenhu  
       2017-03-24 11:14:29 +08:00
    @bianhua 跟语言没太大关系的,真心想死的人,没人拦得住
    blackshadow
        56
    blackshadow  
       2017-03-24 11:21:04 +08:00
    不好意思。报错了。 Parse error: syntax error, unexpected '.9' (T_DNUMBER), expecting ',' or ';' 你们是怎么运行的?
    testlc
        57
    testlc  
       2017-03-24 11:22:09 +08:00
    遇到坑就不能绕道走吗?非要在上面拉条钢丝去走。
    hj2002007
        58
    hj2002007  
       2017-03-24 12:45:12 +08:00
    echo '6+5' . 9+7;
    考察 内容有:
    运算优先级
    隐式转换
    1.按照优先级 从左到右
    '6+5' . 9 : 左边是字符串 所以字符连接 是“ 6+59 “
    2.隐式转换 (整型)
    “ 6+59 “ 按照规则 转化为 6 因为出现了 + 所以只转换 6 为数字
    3.加法运算
    6+7 = 13

    不清楚问题的可以 看看《 php 编程》这本书 对这些讲解还是很清楚的

    不过私以为 作为面试题 不是很合适 因为好久没练习了
    wavingclear
        59
    wavingclear  
       2017-03-24 12:50:31 +08:00
    真是 13 ,没报错, PHP7 环境
    果然没记住算数+和字符串.是同一个优先级
    KasonPasser
        60
    KasonPasser  
       2017-03-24 13:31:37 +08:00
    为什么要写这样的代码?🤔🤔🤔
    bianhua
        61
    bianhua  
       2017-03-24 14:12:07 +08:00
    @realpg
    @allenhu

    我的意思是,对 字符串 => Integer 转换进行这样设计,会造成很多问题。

    如果能让无法转换成目标类型的值在转换时返回 Mismatch 之类就好了,就算退一步来说也可以丢出异常让程序停止运行。

    而 PHP 现在的处理方式是将问题压制下去,自己尝试解析字符串给出一个结果。但是它解析出的结果在很多时候都不是合理的。

    '6+5' . (9+7) 是能单单解决这一个问题没错,但是原因只是因为“.”运算符将后面那个 integer 转换成了 string 然后才与字符串'6+5'进行了拼接而已。但是缺陷仍然存在:每次你尝试将一个 string 转换成 integer/float 的时候都冒着风险。
    allenhu
        62
    allenhu  
       2017-03-24 15:20:05 +08:00
    #bash> php -r "echo '6+5' . 9+7;"
    PHP Notice: A non well formed numeric value encountered in Command line code on line 1
    PHP Stack trace:
    PHP 1. {main}() Command line code:0

    Notice: A non well formed numeric value encountered in Command line code on line 1

    Call Stack:
    0.0001 352568 1. {main}() Command line code:0

    13

    如果你说你关了报错,我无话可说
    TIGERB
        63
    TIGERB  
       2017-03-24 15:21:32 +08:00
    @qdpoboy 第二步错了哈,哈哈,求详解
    qdpoboy
        64
    qdpoboy  
       2017-03-24 15:32:36 +08:00 via Android
    @TIGERB 我是说我自己走错了第二步,并非说你…哈哈哈
    Chwaiz
        65
    Chwaiz  
       2017-03-24 15:41:34 +08:00
    Parse error: parse error, expecting `','' or `';''
    TIGERB
        66
    TIGERB  
       2017-03-24 19:41:18 +08:00
    @qdpoboy 哈哈
    jhdxr
        67
    jhdxr  
       2017-03-24 22:43:22 +08:00
    @bianhua 有 notice 级别的提醒的。没说程序员只看 error 别的不管,你看例如 laravel 的项目默认就是哪怕 notice 级别的信息也不能忽略
    mingyun
        68
    mingyun  
       2017-03-25 10:22:02 +08:00
    @TIGERB 厉害了,哥
    bianhua
        69
    bianhua  
       2017-03-25 11:30:12 +08:00
    @allenhu (假定你是回复我的) @jhdxr

    首先,其实,我说的是哪怕 echo intval('6+5' . 9) + 7;的情况。

    另外,奇怪:
    [nick@localhost]~% php -r "phpinfo();" | grep "Loaded Configuration"
    Loaded Configuration File => /etc/php.ini
    [nick@localhost]~% cat /etc/php.ini | grep "error_reporting =\|display_errors ="
    error_reporting = E_ALL
    display_errors = On
    [nick@localhost]~% php -r "phpinfo();" | grep "error_reporting\|display_errors"
    display_errors => STDOUT => STDOUT
    error_reporting => 32767 => 32767
    [nick@localhost]~% php -r "echo E_ALL;"
    32767%

    // 让 PHP 报告 Notice
    [nick@localhost]~% php -r 'echo $a;'
    PHP Notice: Undefined variable: a in Command line code on line 1

    Notice: Undefined variable: a in Command line code on line 1

    // 没有报告 Notice
    [nick@localhost]~% php -r "echo '6+5' . 9 + 7;"
    13%

    [nick@localhost]~% php -v
    PHP 7.0.17 (cli) (built: Mar 15 2017 07:25:27) ( NTS )
    Copyright (c) 1997-2017 The PHP Group
    Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    bianhua
        70
    bianhua  
       2017-03-25 11:57:30 +08:00
    @jhdxr
    @allenhu

    我发现了,这是 7.1 修正的内容:
    https://secure.php.net/ChangeLog-7.php

    > Version 7.1.0
    > .....
    > Number operators taking numeric strings now emit E_NOTICEs or E_WARNINGs when given malformed numeric strings.

    们那么貌似就是在说正在做我所希望的那些变更。

    另外我搜索了一下 "A non well formed numeric value encountered" 这段字符串。发现很多的项目中招了,所以你看,楼主的问题可能并不是完全没有启发作用?
    zhidian
        71
    zhidian  
       2017-03-25 14:11:07 +08:00 via Android
    “比如例子里的 ((int)'6+1') == intval('6+1') == 6 。从其他语言的角度上来看完全属于设计不合理,因为会导致混乱。 ” 其实这不属于设计不合理。这是人类的认知 bug 。举例: 红色的“蓝色”,和蓝色的“红色”,问你这是什么颜色, php 说前者是蓝色,后者是红色,完全没有错啊!人之所以被误导,因为你自己过多解读了。而且从实现难度上, php 那种 string 解析为 int 的方式更简单, c 不也是这样吗? php 错在不同类型还可以用加法。这一点上, Java 做得最好。
    jhdxr
        72
    jhdxr  
       2017-03-25 15:39:36 +08:00
    @zhidian java 里数字之间可以相加,字符串之间可以相加(字符串连接),字符串数字之间也可以相加(同样也是字符串连接); php 至少把数字相加和字符串连接区分开来了。
    zhidian
        73
    zhidian  
       2017-03-25 17:44:30 +08:00 via Android
    @jhdxr Sorry ,试了下 Java 确实可以。
    zhyoulun
        74
    zhyoulun  
       2017-03-26 22:36:32 +08:00
    这种问题。。唉。。捂脸
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3171 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 14:25 · PVG 22:25 · LAX 07:25 · JFK 10:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.