分享一个很基础但是又很考验基本功的面试题
13

今天有一个老同学参加某企业校招一面的时候,面试官问了下面一个问题:

<?php

class Foo
{
    public $bar = 0;
}

$foo = new Foo;
$foo->baz = 0;

$t1 = microtime(true);

for ($i = 0; $i < 2000000; ++$i) {
    $foo->bar = $i;
}

$t2 = microtime(true);

for ($i = 0; $i < 2000000; ++$i) {
    $foo->baz = $i;
}

$t3 = microtime(true);

echo $t2 - $t1, PHP_EOL, $t3 - $t2, PHP_EOL;

// 用PHP7运行上述代码,简述为何第二段代码耗时显著高于第一段代码。

可以说是相当基础了,但是又非常考验基本功。后来我拿这个问题问了好几个自认为精通PHP的同学,(包括面试现场那位在内)他们都无法在不借助google的情况下给出令人满意的回答。
平时还是要多研究,多思考啊。

后续更新:我写了一篇简短的博客回答了这一问题,希望能给大家带来帮助。

Living on the bleeding edge

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 19
LDL1023

$foo->baz = $i; 会触发 __set 魔术方法

3个月前

我认为应该是:多调用2000次__set()

3个月前
xianyunyehe

眼瞎的我 bar baz 没看出来。

3个月前
keer

这道题不但考验眼力还考验魔术方法

3个月前

一个是直接操作属性,一个是先调用魔术方法再操作属性,所以耗时肯定不一样

3个月前

求答案 ?$foo 在循环前之前已经赋值了,感觉不像是 __set的原因。PHP 5.6 非 7 第二段也明显比第一段代码耗时长。不管那个版本 相差都在 3 左右。 也让我不解的是为毛 7.1.7 耗时为什么会这么高,而且比 5.6 还要调出一大截?

经过测试大概值

5.6.37(0.11,0.14)
7.1.7(0.351,0.375)
7.2.0(0.037,0.040)

两段运行时间差对比
5.6.37 大约在 0.03
7.1.7 大约在 0.02
7.2.0 大约在 0.003

结果:运行时间最短 7.2.0, 最长是 7.1.7
3个月前

@悲剧不上演 只会调用一次 __set

3个月前

@xianyunyehe 刚开始我也没看见一个是 bar 一个是 baz

3个月前

老哥,一个bar一个baz,我TM是不是快瞎了

3个月前
CismonX

@FreeMason__set() 的已经很接近了,可惜是错误答案。类 Foo 没有 __set() 魔术方法,所以两种情况下都没有调用它的开销。答案在我刚写的这篇简短的博客里,你可以参考一下。

3个月前
沐雨

英文看不懂。。楼主英语过八级了吧。。大概是因为 zend_object 里面访问动态属性和默认属性的方式不一样?

3个月前

为毛我的跑起来一直是第二段比第一段快啊

file

3个月前

类的属性都存在类的这个properties_table表里,调用属性默认从这里查,不存在的属性会创建一个zend_array来存,多了一步,所以才慢些吧。不知道说的对不对

3个月前
WytheHuang

厉害了, 还是基础不扎实

3个月前
LiCxi

感觉这并不是特别基础。。。毕竟已经涉及到了源码级别了。。。不过还是学到了,哈哈

3个月前

@CismonX 英语能力弱,有无中文版本的地址,

3个月前

@LiCxi 能赐教下吗?很感兴趣

3个月前

bar会在类初始化时,在hash_table中存储,使用时直接在表中查询,baz 也会查询 hash_table ,但由于没有存储 查询的次数会多一些吧(目前不了解php7类外声明成员存储流程) 嗯 估计是这样 (不知道说的对不对,望指教)

3个月前

@simplewater

file

确定没有问反

3个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!