PHP Interview Questions(17)

面试时间:2020年1月7号,星期一,上午十点。


1.What does “&” mean in ‘&$var’?

Passing by Reference

https://www.php.net/manual/en/language.references.pass.php

2.What is MVC?

MVC is a design pattern used to decouple user-interface (view), data (model), and application logic (controller). This pattern helps to achieve separation of concerns.

https://dotnet.microsoft.com/apps/aspnet/mvc

3.What is the difference between $_GET and $_POST?

$_GET — HTTP GET variables
$_POST — HTTP POST variables

https://www.php.net/manual/en/reserved.variables.php

4.What will be the output of each statements below and why?

var_dump(0123 == 123);

var_dump(‘0123’ == 123);

var_dump(‘0123’ === 123);

False
True
False

https://www.php.net/manual/en/language.types.integer.php

5.After the code below is exexuted, what will be the value of $text and what will be strlen($text) return? Explain your answer.

$text = ‘John ‘;

$text[10] = ‘Doe’;

$text = 'John      D';
strlen($text) = 11;

Javascript

1.What is the potential pitfall with using typeof bar == “object” to determine if bar is an object? How can this pitfall be avoided?

typeof null == "object"
bar != null && typeof bar == "object"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof

2.What is NaN? What is its type? How can you reliably test if a value is equal to NaN?

Not a number
Number
isNaN()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN

3.What is the difference between jQuery.get() and jQuery.ajax()?

$.get(url, data, success, dataType) is a shorthand Ajax function, which is equivalent to:

$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

https://api.jquery.com/jQuery.get/

4.Write a simple function(less than 80 characters) returns a boolean indicating whether or not a string is palindrome.

A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward or forward. Allowances may be made for adjustments to capital letters, punctuation, and word dividers.

console.log(isPalindrome("level"));                    // logs 'true'
console.log(isPalindrome("levels"));                   // logs 'false'
console.log(isPalindrome("A car, a man, a maraca"));   // logs 'true'

function isPalindrome(str) {
    str = str.replace(/\W/g, "").toLowerCase();
    return str.split("").reverse().join("") == str;
}

60 total views, 6 views today

【翻译】MySQL 优化概述

原文链接:https://dev.mysql.com/doc/refman/8.0/en/optimize-overview.html


数据库性能取决于数据库层面的多个因素,例如表、查询和配置。这些软件构造会导致硬件层面的 CPU 和 I/O 操作,你必须尽可能最小化并提高效率。当你刚开始优化数据库性能的时候,首先你要学习软件方面的高级规则和准则,和使用系统时间测量性能。当你成为专家后,你将了解更多的内部细节,并开始测量 CPU 周期和 I/O 操作等指标。

普通用户的目标是从现有的软件和硬件配置中获得最佳的数据库性能。高级用户则会寻找机会来改进 MySQL 软件本身,或者开发自己的存储引擎和硬件设备来扩展 MySQL 生态系统。

数据库层面优化

使数据库应用变快的最重要因素是其基本设计:

表结构是否正常?特别是列是否具有正确的数据类型,并且每个表是否具有适用于工作类型的相应列?例如,需要频繁更新的应用程序通常有许多表,但列很少,而分析大量数据的应用程序通常只有很少的表,但有许多列。

是否使用了正确的索引来提高查询效率?

你是否为每个表选择适当的存储引擎,并且充分利用每种存储引擎的优势和功能?特别是选择事务性存储引擎(如 InnoDB)还是非事务性存储引擎(如 MyISAM)对于性能和可伸缩性非常重要。

注意
InnoDB 是新表的默认存储引擎。实际上,先进的 InnoDB 性能特点意味着 InnoDB 表通常优于更简单的 MyISAM 表,尤其是对于繁忙的数据库。

是否每个表都使用适当的行格式?此选项还取决于用于表的存储引擎。特别是,压缩表占用的磁盘空间较少,因此读取和写入数据所需的磁盘 I/O 更少。压缩可用于具有 InnoDB 表的所有类型的工作负载以及只读的 MyISAM 表。

应用程序是否使用适当的锁定策略?例如,在可能的情况下允许共享访问,以便数据库操作可以同时运行,并在适当时请求独占访问,以便关键操作获得最高优先级。同样,存储引擎的选择也非常重要。InnoDB 存储引擎无需您参与即可处理大多数锁定问题,从而在数据库中实现更好的并发性,并减少代码的实验和调优量。

所有用于缓存的内存区域大小是否正确?也就是说,足够大,可以容纳频繁访问的数据,但规模不够大,以至于使物理内存过载并导致分页。要配置的主要内存区域是 InnoDB 缓冲池和 MyISAM 密钥缓存。

硬件层面优化

随着数据库变得越来越繁忙,任何数据库应用程序最终都达到硬件限制。DBA 必须评估是否可以调整应用程序或重新配置服务器以避免这些瓶颈,或者是否需要更多的硬件资源。系统瓶颈通常来自以下来源:

磁盘查找。磁盘查找数据段需要时间。对于现代磁盘,其平均时间通常低于 10 毫秒,因此理论上我们可以做大约 100 个查找秒。此时间使用新磁盘进行缓慢改进,并且很难针对单个表进行优化。优化寻道时间的方法是将数据分发到多个磁盘上。

磁盘读取和写入。当磁盘处于正确位置时,我们需要读取或写入数据。使用现代磁盘,一个磁盘至少可提供 10*20MB/s 的吞吐量。这比查找更容易优化,因为可以从多个磁盘并行读取。

CPU 周期。当数据位于主内存中时,我们必须处理它以获得结果。与内存量相比,使用大型表是最常见的限制因素。但是,对于小桌子,速度通常不是问题。

内存带宽。当 CPU 需要的数据超过 CPU 缓存容量时,主内存带宽将成为瓶颈。对于大多数系统来说,这是一个不常见的瓶颈,但需要注意。

平衡可移植性和性能

要在便携式 MySQL 程序中使用面向性能的 SQL 扩展,你可以把语句中的 MySQL 特有关键字放到 /*! */ 注释分隔符里面。其他 SQL 服务器会忽略注释的关键字。有关撰写注释的信息,请看 Section 9.6, “Comment Syntax”

1,809 total views, 16 views today

PHP Interview Questions(14)

面试时间:2019年11月20号,星期三,下午两点。


最近的项目中有使用 Laravel 吗?Laravel 的目录结构。

https://laravel.com/docs/6.x/structure

一道编程测试题。(代码点这里)

With the best of your knowledge, create 2 Apis as following: 

1 - Endpoint: /mail/contact

Description: This endpoint is used to send contact form to a specific email, It needs to use the SMTP server provided to dispatch the email to the target user, the email must include Name, Email, Message, and optionally an Attachment

Required Payload: 

{
   name: String,
   email: String,
   message: String,
   attachment: File
}

Tasks

- [ ] Send email using sendgrid to a configurable user email
- [ ] Handle errors
- [ ] Send attachments
- [ ] Send formatted html emails (can be vary basic using tags like div, b, pre etc)

2 - Endpoint: /mail/subscription

Description: This endpoint is used to store user subscription emails, the goal is to keep every email stored in a persistent storage, where it can be later retrieve for further usage. 

Required Payload: { email: string }

Tasks:

- [ ] Handles the case of duplicated entries
- [ ] Persist on local database

Additional Requirements: 

The apis has to work asynchronously (Non Blocking), follow RESTful conventions, clean code, follow Laravel standards, and lastly don’t use excuses like: “I didn’t do this because it’s was a simple project i didn’t felt it was necessary” we want see what you are capable of so do everything that’s under your knowledge. 

Deliverable:
- A ZIP of the project (without the vendor folder)

说说你对设计模式的理解和你运用设计模式的实例。

设计原则 > 设计模式

装饰器模式

适配器模式

你对PHP新版本的特性有关注吗?7.4 有哪些新特性你比较喜欢。

https://laravel-news.com/tag/php74

// 类型属性
https://wiki.php.net/rfc/typed_properties_v2

// 箭头函数
https://wiki.php.net/rfc/arrow_functions_v2

// 数组扩展运算符
https://wiki.php.net/rfc/spread_operator_for_array

What‘s your favorite framework?Why?

Laravel

Document, Community, Packages, Eloquent ORM(ActiveRecord)

https://www.appclonescript.com/laravel-pros-cons/

What‘s the difference between left join and right join?

Can you explain what‘s Eager Loading?

https://laravel.com/docs/6.x/eloquent-relationships#eager-loading

//If we have 25 books, this loop would run 26 queries

$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}

//For this operation, only two queries will be executed
$books = App\Book::with('author')->get();

foreach ($books as $book) {
    echo $book->author->name;
}

549 total views, 16 views today

寒冬

2019 年 10 月 25 日下午六点零几分,离下班还有不到一个小时,突然接到HR的“DING”:来一趟Wework一楼小会议室。

我想了一下就知道大概是什么事情了,说实话还是有一点突然的,但是一切皆有征兆。已经两个月没发工资了,产品部门已经好久没提需求了,我们部门领导也已经不来上班了。大家心里都知道这家公司已经完了,就等什么时候宣布死亡了。

然后我走进小会议室,两个 HR,通知我今天就是最后一天了,也不用交接了,赶紧收拾一下,把电脑交了就可以走人了。

HR 说你也知道我们公司的情况,我们也不容易,其中一个 HR 也是今天最后一天。稍微寒暄了一下,接着就开始谈赔偿。

工资算到 10 月 25 号,社保交到 10 月份,给半个月工资赔偿。我不同意,至少两个月工资赔偿。

再算一下调休和年假。

年假:还剩两天年假。【2】

调休:还剩一天调休。但是国庆前一天,下午 6 点开始封路,我们部门领导让 5 点半提前下班,强行算作用了半天调休。【0.5】

谈了一个小时还有没吃饭,肚子已经饿得呱呱叫了。不想为了 0.5 天争来争去,就签了离职协议,交了电脑,收拾一下东西走人。

加起来一共还欠我三个月工资,两个月的赔偿,两天年假,半天调休。承诺说十月底会先发第一笔,11 月 20 号结清工资和赔偿。我说如果到时间没发我就去劳动仲裁。

那么现在已经是 11 月 25 号了,整整一个月过去了,工资和赔偿发了没有呢?

10 月 31 号发了八月份的基本工资: 4950。至于剩下的部分,没有任何消息。

顺便说一下,上个周五(11 月 22 号)下午的时候路过Weowrk,还碰到老板了,Hubert 看起来好像心情还不错。

接下来我要开始去劳动仲裁了。时值寒冬,所幸的是,暂时还有一点积蓄,交得起房租,吃得起饭,坚持得下去。

519 total views, 4 views today

PHP Interview Questions(13)

面试时间:2019-11-13 星期三,下午两点。


Yii2 实现原理

Yii2 生命周期

Request Lifecycle
https://www.yiiframework.com/doc/guide/2.0/en/start-workflow

快速排序算法。

分治,递归,每一次递归能够确定一个数的位置。

不稳定算法,平均算法时间复杂度 O(nlog2n),平均空间复杂度 O(log2n)。

<?php

/**
 * Quick Sort Implement 1
 * @param array $array
 * @return array
 */
function quickSort(array $array) {
    if (count($array) <= 1) {
        return $array;
    }

    $middle = $array[0];
    $left = [];
    $right = [];

    for ($i = 1; $i < count($array); $i++) {
        if ($array[$i] < $middle) {
            $left[] = $array[$i];
        } else {
            $right[] = $array[$i];
        }
    }

    return array_merge(quickSort($left), [$middle], quickSort($right));
}

/**
 * Quick Sort Implement 2
 * @param array $array
 * @param  int $start
 * @param  int $end
 */
function quickSort2(array &$array, int $start, int $end) {
    if ($start >= $end) {
        return;
    }

    $i = $start;
    $middle = $array[$start];

    for ($j = $start + 1; $j <= $end; $j++) {
        if ($array[$j] < $middle) {
            $i++;
            exchange($array[$i], $array[$j]);
        }
    }

    exchange($array[$i], $array[$start]);

    quickSort2($array, $start, $i - 1);
    quickSort2($array, $i + 1, $end);
}

function exchange(&$a, &$b) {
    [$a, $b] = [$b, $a];
}

function printArray($array) {
    foreach ($array as $value) {
        echo $value, " ";
    }
    echo "\n";
}

$array = [6, 5, 3, 1, 8, 7, 2, 4];
printArray(quickSort($array));
quickSort2($array, 0, count($array) - 1);
printArray($array);

自动加载原理。

https://zyf.im/2019/04/28/php-composer-basic/

工作中遇到的最难的问题是什么?怎么解决的。

173 total views, 1 views today

PHP Interview Questions(12)

面试时间:2019 年 11 月 5 日,星期二,下午三点。


现在使用的 PHP 版本,有哪些新特性。

PHP 7.2

https://tanghengzhi.com/whats-new-in-php-72/

聊一聊PHP SPL,迭代器和生成器。

/**
 * https://www.php.net/manual/en/intro.spl.php
 **/
The Standard PHP Library (SPL) is a collection of interfaces and classes that are meant to solve common problems.

No external libraries are needed to build this extension and it is available and compiled by default in PHP 5.0.0.

SPL provides a set of standard datastructure, a set of iterators to traverse over objects, a set of interfaces, a set of standard Exceptions, a number of classes to work with files and it provides a set of functions like spl_autoload_register()

/**
 * https://www.php.net/manual/zh/class.iterator.php
 **/

/**
 * https://www.php.net/manual/zh/language.generators.overview.php
 **/

TCP 和 UDP 的区别。

        UDP	TCP
是否连接	无连接	面向连接
是否可靠	不可靠传输,不使用流量控制和拥塞控制	可靠传输,使用流量控制和拥塞控制
连接对象个数	支持一对一,一对多,多对一和多对多交互通信	只能是一对一通信
传输方式	面向报文	面向字节流
首部开销	首部开销小,仅8字节	首部最小20字节,最大60字节
适用场景	适用于实时应用(IP电话、视频会议、直播等)	适用于要求可靠传输的应用,例如文件传输

https://segmentfault.com/a/1190000018582150

什么是 Socket 编程。

Socket 是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

https://www.jianshu.com/p/f671d3895d13

MySQL 索引。

https://dev.mysql.com/doc/refman/8.0/en/optimize-overview.html

MySQL 事务。

https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_transaction

MySQL 读写分离。

'mysql' => [
    'read' => [
        'host' => [
            '192.168.1.1',
            '196.168.1.2',
        ],
    ],
    'write' => [
        'host' => [
            '196.168.1.3',
         ],
    ],
    'sticky'    => true,
    'driver'    => 'mysql',
    'database'  => 'database',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
],

https://laravel.com/docs/6.x/database

常见的 Redis 数据结构。

https://www.runoob.com/redis/redis-data-types.html

Redis 集合(Set) 常用命令。

https://www.runoob.com/redis/redis-sets.html

Redis cluster 原理。

https://redis.io/topics/cluster-tutorial

Git Rebase

https://git-scm.com/book/en/v2/Git-Branching-Rebasing

https://docs.microsoft.com/en-us/azure/devops/repos/git/merging-with-squash?view=azure-devops

Git 工作原理

http://marklodato.github.io/visual-git-guide/index-zh-cn.html

165 total views, 2 views today

PHP Interview Questions(11)

面试时间:2019 年 11 月 4 日,星期一,下午两点。


1. 给定一个二维数组,数组每一行从左到右都是递增的,每一列也是递增的。请完成一个函数,输入为如上二维数组和一个整数,函数功能为判断该整数是否存在于数组中。时间复杂度尽可能的低。(请说明你的算法的复杂度。)

下面是一个例子:

二维数组:

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15

数字:9

<?php

$array = [
    [1, 2, 8, 9],
    [2, 4, 9, 12],
    [4, 7, 10, 13],
    [6, 8, 11, 15],
];

$number = 9;

/**
 * 最简单的方法就是遍历整个数组
 * 时间复杂度 O(Row*Column-1)
 */
function findNumberInArray($array, $number) {
    foreach ($array as $rowArray) {
        foreach ($rowArray as $value) {
            echo $value, " ";
            if ($number == $value) {
                return true;
            }
        }
    }

    return false;
}

/**
 * 从二维数组的左下角开始逐行查找
 * 时间复杂度 O(Row+Column-1)
 */
function findNumberInArray2($array, $number) {
    $minRow = 0;
    $minColumn = 0;
    $maxRow = count($array) - 1;
    $maxColumn = count($array[0]) - 1;

    if ($number < $array[0][0] || $number > $array[$maxRow][$maxColumn]) {
        return false;
    }

    for ($row = $maxRow; $row >= $minRow; $row--) {
        for ($column = $minColumn; $column <= $maxColumn; $column++) {
            echo $array[$row][$column], " ";
            if ($array[$row][$column] == $number) {
                return true;
            }
            if ($array[$row][$column] > $number) {
                break;
            }
            if ($array[$row][$column] < $number) {
                $minColumn = $column + 1;
            }
        }
    }

    return false;
}

/**
 * 从二维数组的右上角开始逐行查找
 * 时间复杂度 O(Row+Column-1)
 */
function findNumberInArray3($array, $number) {
    $minRow = 0;
    $minColumn = 0;
    $maxRow = count($array) - 1;
    $maxColumn = count($array[0]) - 1;

    if ($number < $array[0][0] || $number > $array[$maxRow][$maxColumn]) {
        return false;
    }
    
    for ($row = $minRow; $row <= $maxRow; $row++) {
        for ($column = $maxColumn; $column >= $minColumn; $column--) {
            echo $array[$row][$column], " ";
            if ($array[$row][$column] == $number) {
                return true;
            }
            if ($array[$row][$column] > $number) {
                $maxColumn = $column - 1;
            }
            if ($array[$row][$column] < $number) {
                break;
            }
        }
    }

    return false;
}

echo "/**
* 最简单的方法就是遍历整个数组
* 时间复杂度 O(Row*Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray($array, $number);
    echo "\n";
}

echo "/**
* 从二维数组的左下角开始逐行查找
* 时间复杂度 O(Row+Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray2($array, $number);
    echo "\n";
}

echo "/**
* 从二维数组的右上角开始逐行查找
* 时间复杂度 O(Row+Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray3($array, $number);
    echo "\n";
}

2.把数组最开始的若干个元素搬到数组末尾,称为数组的旋转。给定一个递增数组的旋转数组,请完成一个函数,时间复杂度尽可能的低,输出该旋转数组的最小元素。并给出复杂度。

例如输入数组(4,5,6,7,8,10,1,2,3),输出 1。

<?php

$array = [4, 5, 6, 7, 8, 10, 1, 2, 3];

/**
 * 使用 min() 函数
 * 时间复杂度:O(N)
 * 源码:https://github.com/php/php-src/blob/master/ext/standard/array.c
 */
echo min($array), "\n";

/**
 * 使用二分查找法
 * 时间复杂度:O(log2N)
 */
function findMinimumNumberInArray($array, $start = 0, $end = null) {
    if ($end == null) {
        $end = count($array) - 1;
    }

    if ($start == $end) {
        return $array[$start];
    }

    $middle = floor(($start + $end) / 2);

    if ($array[$start] < $array[$end]) {
        return findMinimumNumberInArray($array, $start, $middle);
    } else {
        return findMinimumNumberInArray($array, $middle, $end);
    }
}

echo findMinimumNumberInArray($array), "\n";

3.输入一个字符串,输出该字符串中字符的所有组合。(不限编程语言,请注明你选择的语言)

下面是一个例子:

输入参数:字符串:“abc”

输出:“a”, “b”, “c”, “ab”, “ac”, “bc”, “abc”

<?php

$string = "abc";
$length = strlen($string);

/**
 * 使用二进制表示不同的排列组合
 * 
 * 0 0 1 a
 * 0 1 0 b
 * 0 1 1 ab
 * 1 0 0 c
 * 1 0 1 ac
 * 1 1 0 bc
 * 1 1 1 abc
 */
 for ($i = 1; $i < 1 << $length; $i++) {
     for ($j = 0; $j < $length; $j++) {
         if ($i & (1 << $j)) {
             echo $string[$j];
         }
     }
     echo "\n";
 }

参考:

剑指Offer面试题:2.二维数组中的查找

剑指Offer面试题:7.旋转数组的最小数字

剑指Offer面试题:26.字符串的排列

307 total views, 1 views today