Похоже вакансию сняли, по крайней мере уже пару дней не видел, так что выкладываю свои варианты ответов.
Ни на что не претендую (особенно на правильность решений), просто мои ответы, но рад буду критике, особенно если дадут правильный ответ :)
К сожалению пикабу не поддерживает форматирование кода :(
Вопрос 14. Напишите, пожалуйста, код для сортировки массива $arr по полю id. Структура массива:
$arr = [
['id' => 1, ...],
['id' => 2, ...],
['id' => 3, ...],
...
];
Ответ:
usort($arr, function ($a, $b) {
if ($a['id'] === $b['id']) {
return 0;
}
return ($a['id'] < $b['id']) ? -1 : 1;
});
Вопрос 15. Есть переменная $url, которая содержит URL вида http://pikabu.ru/2018/01/dd/text.
Необходимо написать код валидации этой переменной, используя одно регулярное выражение, по средующим критериям:
- dd - двузначное число в месяце;
- text - произвольный текст длиной от 1 до 20 символов, в котором допустимы только латинские символы нижнего регистра, нижнее подчеркивание _ и точка .;
- ссылка может иметь произвольный поддомен латинскими буквами от 3 до 10 символов, например http://www.pikabu.ru;
- протокол может быть как http, так и https.
Ответ:
Я просто ответил вот такой регуляркой
/^(http|https):\/\/([a-zA-Z]{3,10}\.)?pikabu\.ru\/([12]\d{3})\/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/([a-z_\.]{1,20})$/
Вопрос 16. Дана строка $str с произвольным текстом (1 символ - 1 байт). Необходимо без использования циклов и рекурсий подсчитать количество символов в этой строке, у которых ascii код кратен 3.
$str = 'hello world';
$cnt = ... ваш код ...; // = 6
Ответ:
$cnt = count(
array_filter(
unpack("C*", $str),
function ($code) {
return $code % 3 === 0;
}
)
);
Вопрос 17. Необходимо сформировать SQL запрос к таблице user_marks, который выводит количество человек по возрасту, полу и наличию/отсутствию хорошей оценки (хорошая оценка = 5).
Формат вывода: age, gender, is_positive_mark, cnt, где:
- is_positive_mark = 1 если оценка mark = 5, 0 - оценка меньше 5;
- cnt - количество записей.
Результаты нужно отсортировать по возрасту age и is_positive_mark в обратном порядке. А также необходимо выводить только группы, где количество записей cnt больше 1.
CREATE TABLE `user_marks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`gender` tinyint(1) DEFAULT '0' COMMENT '0 - male, 1 - female',
`mark` int(11) DEFAULT NULL COMMENT '1-5',
PRIMARY KEY (`id`)
)
Ответ:
SELECT age,
gender,
if(mark < 5, 0, 1) AS is_positive_mark,
count(*) AS cnt
FROM user_marks
GROUP BY age,
gender,
is_positive_mark
HAVING cnt > 1
ORDER BY age DESC,
is_positive_mark DESC
Вопрос 18. Напишите, пожалуйста, реализацию функции calc для представленного ниже кода
$sum = function($a, $b) { return $a + $b; };
calc(5)(3)(2)($sum); // 10
calc(1)(2)($sum); // 3
calc(2)(3)('pow'); // 8
Ответ:
function calc()
{
$arg = func_get_arg(0);
$args = [];
if (func_num_args() === 2) {
$args = func_get_arg(1);
}
if (is_numeric($arg)) {
$args[] = $arg;
return function ($arg) use ($args) {
return calc($arg, $args);
};
}
if (is_callable($arg)) {
$total = $args[0];
for ($i = 1; $i < count($args); $i++) {
$total = $arg($total, $args[$i]);
}
return $total;
}
if (is_string($arg)) {
if ($arg === 'pow') {
return pow($args[0], $args[1]);
}
}
}
Вопрос 19. В указанном ниже коде закралась ошибка, приводящая к неверному результату. Также, сам код явно нуждается в улучшении :)
Предложите, пожалуйста, исправленный и улучшенный вариант этого кода.
$maxValue = 10;
function isUserBan($arr) {
global $maxValue;
$sum = 0;
for ($i = 0; $i < count($arr); $i++) {
$sum += $arr[$i];
}
if ($sum >= $maxValue) {
return true;
}
else {
return false;
}
}
$users = array(
'user1' => array(1, 4.1, 3.3, 1.12),
'user2' => array(2, 4.1, 8, 0.2),
'user3' => array(2, 4.2, 9, 12),
);
$maxValue += 4.3;
foreach ($users as $k => $v) {
echo $k . ' is ' . (isUserBan($v) ? 'banned' : 'not banned') . '<br>';
}
Ответ:
function isUserBan($arr, $maxValue = 10)
{
if (array_sum($arr) >= $maxValue) {
return true;
}
return false;
}
$users = [
'user1' => [1, 4.1, 3.3, 1.12],
'user2' => [2, 4.1, 8, 0.2],
'user3' => [2, 4.2, 9, 12],
];
$maxValue = 14.3;
foreach ($users as $index => $user) {
echo $index . ' is ' . (isUserBan($user, $maxValue) ? 'banned' : 'not banned') . '<br>';
}
Вопрос 20. Так вышло, что вам достался фрагмент кода, написанный гик-злодеем. Необходимо его максимально упростить: убрать и упростить лишние конструкции и выражения так, чтобы логика работы функции не поменялась.
function calc($a) {
$a = ($a & 0x3f) + 1.9 >> 0;
$c = !1 !== !!+$a ? --$a : $a++ ? ~~$a : $a++;
if (!$c == false) {
for ($a -=- ($c * 3), $c = $a; $a < $c << 0b10;) {
$a *= $c;
}
return 0 | (int)$a;
} else {
return 0 | sqrt($c);
}
}
Ответ:
function calc($a) {
$a = ($a & 0x3f) + 1;
if ($a === 1) {
return 0;
}
if ($a === 0) {
$a += 1;
} else {
$a -= 1;
}
$a = $a + $a * 3;
return pow($a, 2);
}
Вопрос 21. Предложите способ упаковки следующих данных о пользователе с самым компактным результатом (бинарный результат допускается):
$isAdmin = false;
$isModerator = true;
$isApproved = false;
$gender = 1; // возможные значения: 0, 1, 2
$showAdultContent = false;
Ответ:
const ADMIN_FLAG = 1 << 0;
const MODERATOR_FLAG = 1 << 1;
const APPROVED_FLAG = 1 << 2;
const ADULT_CONTENT_FLAG = 1 << 3;
const GENDER1_FLAG = 1 << 4;
const GENDER2_FLAG = 1 << 5;
// ZIP
$userFlags = 0;
$userFlags += $isAdmin ? ADMIN_FLAG : 0;
$userFlags += $isModerator ? MODERATOR_FLAG : 0;
$userFlags += $isApproved ? APPROVED_FLAG : 0;
$userFlags += $showAdultContent ? ADULT_CONTENT_FLAG : 0;
if ($gender === 1) {
$userFlags += GENDER1_FLAG ;
}
if ($gender === 2) {
$userFlags += GENDER2_FLAG ;
}
// UNZIP
$isAdmin = (bool)($userFlags & ADMIN_FLAG );
$isModerator = (bool)($userFlags & MODERATOR_FLAG );
$isApproved = (bool)($userFlags & APPROVED_FLAG );
$showAdultContent = (bool)($userFlags & ADULT_CONTENT_FLAG );
$gender = 0;
if ($userFlags & GENDER1_FLAG ) {
$gender = 1;
}
if ($userFlags & GENDER2_FLAG ) {
$gender = 2;
}
Вопрос 22. Ниже представлен фрагмент кода, использующего класс Users:
$foo = new Users;
$foo[] = 'Guest #' . count($foo);
$foo[] = 'Guest #' . count($foo);
echo $foo;
unset($foo);
Если выполнить этот код, то в stdout напечатается следующее:
Welcome Guest #0
Welcome Guest #1
Total users: 2
Goodby Guest #0, Guest #1
Пожалуйста, напишите реализацию класса Users (не более 50 строк кода).
Ответ:
class Users implements ArrayAccess, Countable
{
private $users = [];
public function offsetExists($offset)
{
return isset($this->users[$offset]);
}
public function offsetGet($offset)
{
return $this->users[$offset];
}
public function offsetSet($offset, $value)
{
if ($offset) {
$this->users[$offset] = $value;
} else {
$this->users[] = $value;
}
echo "Welcome ${value}".PHP_EOL;
}
public function offsetUnset($offset) {}
public function count()
{
return count($this->users);
}
public function __toString()
{
return 'Total users: '.$this->count().PHP_EOL;
}
public function __destruct()
{
echo 'Goodby ' . implode(', ', $this->users) . PHP_EOL;
}
}
@0x00, @admin, если я ошибся в том что вакансию уже сняли, то удалите пост