Пример запроса (первая клетка). System одинаковый во всех запросах прогона, user — свой вопрос для каждой клетки:
| Клетка | Тема | Утверждение | Ответ |
Результат | Обоснование |
T01-L1 3.16 c | 语法与运算符 | 双引号字符串和单引号字符串的处理方式完全相同,区别只在速度。 | «否» Пояснение: 双引号支持变量插值和转义序列,而单引号仅支持反斜杠和单引号的转义,功能上存在显著差异。
Raw{"answer": "否", "解释": "双引号支持变量插值和转义序列,而单引号仅支持反斜杠和单引号的转义,功能上存在显著差异。"} | верно | В двойных кавычках работают интерполяция переменных и escape-последовательности, в одинарных — нет. |
T01-L2 0.36 c | 语法与运算符 | ?? 运算符按 isset 的语义工作,对未定义的变量不会产生任何警告。 | «是» Пояснение: ?? 运算符专门用于处理可能为 null 或未定义的值,访问未定义变量时不会抛出 Warning 或 Notice。
Raw{"answer": "是", "解释": "?? 运算符专门用于处理可能为 null 或未定义的值,访问未定义变量时不会抛出 Warning 或 Notice。"} | верно | ?? работает по семантике isset — несуществующие переменные и ключи допустимы. |
T01-L3 0.25 c | 语法与运算符 | 下面代码输出什么:echo 'a', 'b'; | «ab» Пояснение: echo 支持多个参数,用逗号分隔,直接拼接输出。
Raw{"answer": "ab", "解释": "echo 支持多个参数,用逗号分隔,直接拼接输出。"} | верно | echo принимает список аргументов: ab. |
T01-L4 0.31 c | 语法与运算符 | print 返回值 1,可以用在表达式内部。 | «是» Пояснение: print 是语言结构但会隐式返回 1,因此可以在表达式中使用。
Raw{"answer": "是", "解释": "print 是语言结构但会隐式返回 1,因此可以在表达式中使用。"} | верно | print — выражение со значением 1, в отличие от echo, который значения не возвращает. |
T01-L5 0.23 c | 语法与运算符 | 如果左侧操作数为假,?: 运算符(Elvis 运算符)返回左侧操作数。 | «否» Пояснение: Elvis 运算符 ?: 在左侧为假时返回右侧操作数,而非左侧。
Raw{"answer": "否", "解释": "Elvis 运算符 ?: 在左侧为假时返回右侧操作数,而非左侧。"} | верно | Наоборот: $a ?: $b возвращает $a, если он истинный, иначе $b. |
T01-L6 0.43 c | 语法与运算符 | 在 PHP 8 中,连接运算符(.)的优先级低于加法和减法。 | «否» Пояснение: 在 PHP 中,连接运算符(.)的优先级高于加法和减法,例如 '1' . 2 + 3 结果为 '15' 而不是 '13'。
Raw{"answer": "否", "解释": "在 PHP 中,连接运算符(.)的优先级高于加法和减法,例如 '1' . 2 + 3 结果为 '15' 而不是 '13'。"} | неверно верный: «是» | С PHP 8 (RFC concat precedence) '.' имеет приоритет ниже арифметики: 'сумма: ' . 2 + 3 → 'сумма: 5' (в PHP 7 было иначе). |
T01-L7 0.38 c | 语法与运算符 | 表达式 2 ** 3 ** 2 在 PHP 中按 (2 ** 3) ** 2 计算,即等于 64。 | «否» Пояснение: PHP 中 ** 运算符是右结合的,因此 2 ** 3 ** 2 计算为 2 ** (3 ** 2) = 2 ** 9 = 512。
Raw{"answer": "否", "解释": "PHP 中 ** 运算符是右结合的,因此 2 ** 3 ** 2 计算为 2 ** (3 ** 2) = 2 ** 9 = 512。"} | верно | ** право-ассоциативен: 2 ** (3 ** 2) = 2 ** 9 = 512. |
T01-L8 0.4 c | 语法与运算符 | 下面代码输出什么字符串:echo '总和: ' . 2 + 3;(PHP 8)? | «总和: 5» Пояснение: 字符串连接运算符 . 的优先级低于算术运算符 +,所以先计算 2 + 3 = 5,再与字符串拼接。
Raw{"answer": "总和: 5", "解释": "字符串连接运算符 . 的优先级低于算术运算符 +,所以先计算 2 + 3 = 5,再与字符串拼接。"} | верно | Парная к verify-клетке про приоритет: 'сумма: 5'. |
T02-L1 0.41 c | 类型与比较 | 在严格比较(===)下,数组被视为相等,与元素顺序无关。 | «否» Пояснение: 在 PHP 中,使用严格比较(===)比较数组时,不仅要求数组的元素和值相等,还要求元素的顺序和类型完全一致。
Raw{"answer": "否", "解释": "在 PHP 中,使用严格比较(===)比较数组时,不仅要求数组的元素和值相等,还要求元素的顺序和类型完全一致。"} | верно | === для массивов требует совпадения и значений, и их порядка. |
T02-L2 0.41 c | 类型与比较 | 表达式 0 == false 返回 false,因为这是严格比较。 | «否» Пояснение: 表达式 0 == false 使用宽松比较(==),在 PHP 中会返回 true;严格比较(===)0 === false 才返回 false。
Raw{"answer": "否", "解释": "表达式 0 == false 使用宽松比较(==),在 PHP 中会返回 true;严格比较(===)0 === false 才返回 false。"} | верно | Наоборот: == — нестрогое сравнение и возвращает true; строгое — это === (0 === false → false). |
T02-L3 0.41 c | 类型与比较 | 在 PHP 8 中,表达式 "abc" == 0 的结果是 true。 | «否» Пояснение: PHP 8 改进了非数字字符串与数字的松散比较,"abc" 不再被转换为 0,因此比较结果为 false。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "PHP 8 改进了非数字字符串与数字的松散比较,\"abc\" 不再被转换为 0,因此比较结果为 false。" ⏎ } ⏎ ``` | верно | С PHP 8 нечисловая строка сравнивается как строка: "abc" == "0" → false (в PHP 7 было true). |
T02-L4 0.25 c | 类型与比较 | 在宽松比较下,null 同时等于 0、空字符串和 false。 | «是» Пояснение: 在 PHP 宽松比较中,null 等于 0、空字符串和 false。
Raw{"answer": "是", "解释": "在 PHP 宽松比较中,null 等于 0、空字符串和 false。"} | верно | null == 0, null == "" и null == false — все true. |
T02-L5 0.31 c | 类型与比较 | 表达式 (int) '42abc' 返回什么? | «42» Пояснение: PHP 将字符串开头能识别的整数部分转换为整数,忽略尾部非数字字符。
Raw{"answer": 42, "解释": "PHP 将字符串开头能识别的整数部分转换为整数,忽略尾部非数字字符。"} | верно | Ведущая числовая часть: 42, без ошибок и warning. |
T02-L6 0.29 c | 类型与比较 | 表达式 '5' + 5 返回什么? | «10» Пояснение: 字符串 '5' 会被自动转换为整数 5,然后与 5 相加得到 10。
Raw{"answer": 10, "解释": "字符串 '5' 会被自动转换为整数 5,然后与 5 相加得到 10。"} | верно | Числовая строка приводится: int 10. |
T02-L7 0.27 c | 类型与比较 | 转换为字符串时,false 会变成 "0"。 | «否» Пояснение: 在 PHP 中,布尔值 false 转换为字符串时是 ""(空字符串),而不是 "0"。
Raw{"answer": "否", "解释": "在 PHP 中,布尔值 false 转换为字符串时是 \"\"(空字符串),而不是 \"0\"。"} | верно | false → "", true → "1". |
T02-L8 0.29 c | 类型与比较 | 表达式 0.1 + 0.2 === 0.3 的结果是 false。 | «是» Пояснение: 由于浮点数精度问题,0.1 + 0.2 在 PHP 中严格不等于 0.3。
Raw{"answer": "是", "解释": "由于浮点数精度问题,0.1 + 0.2 在 PHP 中严格不等于 0.3。"} | верно | Двоичная погрешность float: 0.1 + 0.2 = 0.30000000000000004. |
T03-L1 0.27 c | 字符串 | strrev() 能正确反转 UTF-8 字符串。 | «否» Пояснение: strrev() 按字节反转,会破坏多字节字符
Raw{"answer": "否", "解释": "strrev() 按字节反转,会破坏多字节字符"} | верно | strrev переворачивает байты и ломает многобайтовые последовательности. |
T03-L2 0.28 c | 字符串 | str_contains('Hello world', 'world') 返回 true。 | «是» Пояснение: 字符串 'Hello world' 中确实包含子串 'world',str_contains 返回 true。
Raw{"answer": "是", "解释": "字符串 'Hello world' 中确实包含子串 'world',str_contains 返回 true。"} | верно | str_contains с PHP 8.0 проверяет вхождение подстроки. |
T03-L3 0.41 c | 字符串 | str_pad() 只能在字符串右侧补齐。 | «否» Пояснение: str_pad() 支持在左侧、右侧或两侧补齐(通过 pad_type 参数指定 STR_PAD_LEFT, STR_PAD_RIGHT 或 STR_PAD_BOTH)。
Raw{"answer": "否", "解释": "str_pad() 支持在左侧、右侧或两侧补齐(通过 pad_type 参数指定 STR_PAD_LEFT, STR_PAD_RIGHT 或 STR_PAD_BOTH)。"} | верно | STR_PAD_LEFT / STR_PAD_BOTH меняют сторону дополнения. |
T03-L4 0.25 c | 字符串 | 默认情况下 trim() 只去掉空格,不会处理制表符和换行符。 | «否» Пояснение: 默认情况下 trim() 会去掉空格、制表符、换行符等常见空白字符。
Raw{"answer": "否", "解释": "默认情况下 trim() 会去掉空格、制表符、换行符等常见空白字符。"} | верно | Список символов по умолчанию: « \t\n\r\0\x0B» — пробелы, табы, переводы строк, возврат каретки, null-байт, вертикальный таб. Проверено php -r. |
T03-L5 0.28 c | 字符串 | 对 UTF-8 字符串,strlen('你好') 返回多少个字节(BYTES)? | «6» Пояснение: UTF-8 中每个中文字符占 3 字节,2 个字符共 6 字节。
Raw{"answer": 6, "解释": "UTF-8 中每个中文字符占 3 字节,2 个字符共 6 字节。"} | верно | 6 букв по 2 байта: 12. |
T03-L6 0.25 c | 字符串 | 表达式 substr('abcdef', -3) 返回什么? | «def» Пояснение: substr 从倒数第3个字符开始截取到末尾
Raw{"answer": "def", "解释": "substr 从倒数第3个字符开始截取到末尾"} | верно | Отрицательное смещение — с конца: def. |
T03-L7 0.27 c | 字符串 | ucfirst() 会原地修改传入的字符串。 | «否» Пояснение: ucfirst() 返回一个新的字符串,不会修改原始变量。
Raw{"answer": "否", "解释": "ucfirst() 返回一个新的字符串,不会修改原始变量。"} | верно | Строки неизменяемы; ucfirst возвращает новую строку. |
T03-L8 0.29 c | 字符串 | heredoc 支持变量插值,而 nowdoc 不支持。 | «是» Пояснение: Heredoc 使用双引号语法支持变量插值,而 Nowdoc 使用单引号语法不进行变量插值。
Raw{"answer": "是", "解释": "Heredoc 使用双引号语法支持变量插值,而 Nowdoc 使用单引号语法不进行变量插值。"} | верно | Nowdoc — «одинарные кавычки» в тройном синтаксисе: текст как есть. |
T04-L1 0.35 c | 数组 | sort() 函数会保持数组键与值之间的对应关系。 | «否» Пояснение: sort() 函数在对数组排序时,会重置数字键,但保留字符串键。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "sort() 函数在对数组排序时,会重置数字键,但保留字符串键。" ⏎ } ⏎ ``` | верно | sort перенумеровывает ключи; связь сохраняет asort. |
T04-L2 0.33 c | 数组 | 数组中的字符串键 '5' 会存成整数 5。 | «否» Пояснение: PHP 数组键中的字符串 '5' 不会自动转换为整数 5,除非显式强制转换。
Raw{"answer": "否", "解释": "PHP 数组键中的字符串 '5' 不会自动转换为整数 5,除非显式强制转换。"} | неверно верный: «是» | Каноничные десятичные строковые ключи приводятся к int. |
T04-L3 0.33 c | 数组 | in_array() 函数默认使用严格比较(===)。 | «否» Пояснение: in_array() 函数默认使用松散比较(==),第三个参数 strict 默认为 false。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "in_array() 函数默认使用松散比较(==),第三个参数 strict 默认为 false。" ⏎ } ⏎ ``` | верно | По умолчанию сравнение нестрогое; строгое — третий аргумент true. |
T04-L4 0.41 c | 数组 | 不带回调时,array_filter() 会删除数组中所有“空”(falsy)元素。 | «是» Пояснение: array_filter() 不带回调时,默认使用 (bool) 来筛选,即删除所有 falsy 值(如 0, '', null, false 等)。
Raw{"answer": "是", "解释": "array_filter() 不带回调时,默认使用 (bool) 来筛选,即删除所有 falsy 值(如 0, '', null, false 等)。"} | верно | Убирает 0, "", null, false и пустые массивы. |
T04-L5 0.35 c | 数组 | 默认情况下,array_slice() 会保留数组原有的数字键。 | «否» Пояснение: 默认情况下,array_slice() 会将数字键重置为从 0 开始的顺序,除非将 preserve_keys 参数设为 true。
Raw{"answer": "否", "解释": "默认情况下,array_slice() 会将数字键重置为从 0 开始的顺序,除非将 preserve_keys 参数设为 true。"} | верно | По умолчанию ключи перенумеровываются; сохранение — preserve_keys = true. |
T04-L6 0.3 c | 数组 | array_slice([10, 20, 30, 40], 1, 2) 返回什么? | «[20, 30]» Пояснение: array_slice 从索引1开始取2个元素,结果为[20, 30]
Raw{"answer": "[20, 30]", "解释": "array_slice 从索引1开始取2个元素,结果为[20, 30]"} | верно | [20,30]; ключи перенумеровываются. |
T04-L7 0.38 c | 数组 | count(['a' => 1] + ['a' => 9, 'b' => 2]) 的元素个数是多少? | «2» Пояснение: 数组合并时,相同键 'a' 只保留左边的值,因此结果包含 'a' 和 'b' 两个元素。
Raw{"answer": 2, "解释": "数组合并时,相同键 'a' 只保留左边的值,因此结果包含 'a' 和 'b' 两个元素。"} | верно | Оператор + : по ключу 'a' побеждает левый; итого 2. |
T04-L8 0.37 c | 数组 | 从 PHP 8.1 起,展开运算符 [...$a, ...$b] 支持带字符串键的数组。 | «是» Пояснение: PHP 8.1 开始支持展开运算符展开带字符串键的数组。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "PHP 8.1 开始支持展开运算符展开带字符串键的数组。" ⏎ } ⏎ ``` | верно | В 8.0 — только числовые ключи; 8.1 снял ограничение. |
T05-L1 0.49 c | 函数与闭包 | 在同一个调用中,命名参数不能与数组展开 ...$args 组合使用。 | «否» Пояснение: 命名参数可以与数组展开组合使用,例如 function(...$args) 和 function($a, ...$rest) 均可合法存在并调用。
Raw{"answer": "否", "解释": "命名参数可以与数组展开组合使用,例如 function(...$args) 和 function($a, ...$rest) 均可合法存在并调用。"} | верно | Можно: f(...$args, имя: значение). Нельзя только позиционный аргумент после распаковки. |
T05-L2 0.81 c | 函数与闭包 | 不使用 use 的匿名函数能看到外部作用域的变量。 | «是» Пояснение: 在 PHP 中,匿名函数(闭包)可以访问其定义时的外部作用域变量,前提是未使用 `use` 关键字捕获变量或变量位于全局作用域。若变量不在全局作用域且未被 `use` 捕获,则匿名函数默认无法访问局部变量,但在全局作用域中定义的匿名函数可以直接访问全局变量。因此该说法正确。
Raw{"answer": "是", "解释": "在 PHP 中,匿名函数(闭包)可以访问其定义时的外部作用域变量,前提是未使用 `use` 关键字捕获变量或变量位于全局作用域。若变量不在全局作用域且未被 `use` 捕获,则匿名函数默认无法访问局部变量,但在全局作用域中定义的匿名函数可以直接访问全局变量。因此该说法正确。"} | неверно верный: «否» | Без use внешние переменные недоступны; авто-захват только у fn. |
T05-L3 0.39 c | 函数与闭包 | 调用 f(1, 2, 3) 时,function f($a) { return func_num_args(); } 内部的 func_num_args() 返回什么? | «3» Пояснение: func_num_args() 返回传递给函数 f 的实际参数数量,这里是 3 个(1, 2, 3)。
Raw{"answer": 3, "解释": "func_num_args() 返回传递给函数 f 的实际参数数量,这里是 3 个(1, 2, 3)。"} | верно | Считает переданные аргументы: 3. |
T05-L4 0.33 c | 函数与闭包 | 箭头函数 fn 的函数体可以是用花括号包起来的多个表达式。 | «是» Пояснение: 箭头函数 fn 支持使用花括号定义包含多个语句的函数体。
Raw{"answer": "是", "解释": "箭头函数 fn 支持使用花括号定义包含多个语句的函数体。"} | неверно верный: «否» | fn — всегда одно выражение; блок операторов делает обычная анонимная функция. |
T05-L5 0.55 c | 函数与闭包 | 箭头函数 fn 按引用捕获外部变量(惰性地,在使用时才取值)。 | «否» Пояснение: PHP 的箭头函数(fn)通过静态绑定(by value)自动捕获作用域变量,而非按引用(by reference)捕获;变量值在定义时即被固定,外部后续修改不会影响函数内部。
Raw{"answer": "否", "解释": "PHP 的箭头函数(fn)通过静态绑定(by value)自动捕获作用域变量,而非按引用(by reference)捕获;变量值在定义时即被固定,外部后续修改不会影响函数内部。"} | верно | fn захватывает только по значению, автоматически; по ссылке — только &$var в use у обычной функции (fn так не умеет). |
T05-L6 0.45 c | 函数与闭包 | 用 static function () {} 声明的闭包不会捕获 $this。 | «是» Пояснение: 在 PHP 中,使用 `static function () {}` 声明的闭包(静态闭包)确实不会自动捕获调用上下文中的 `$this` 变量,除非显式通过 `use ($this)` 传递。
Raw{"answer": "是", "解释": "在 PHP 中,使用 `static function () {}` 声明的闭包(静态闭包)确实不会自动捕获调用上下文中的 `$this` 变量,除非显式通过 `use ($this)` 传递。"} | верно | static-замыкание отвязано от объекта: $this внутри недоступен. |
T05-L7 0.44 c | 函数与闭包 | 下面代码输出什么:$x = 5; $f = function () use ($x) { return $x; }; $x = 7; echo $f(); | «5» Пояснение: use ($x) 在定义时按值捕获变量,故闭包内 $x 为 5,后续 $x = 7 不影响。
Raw{"answer": 5, "解释": "use ($x) 在定义时按值捕获变量,故闭包内 $x 为 5,后续 $x = 7 不影响。"} | верно | use захватывает по значению в момент создания: 5. |
T05-L8 0.35 c | 函数与闭包 | 在弱类型模式(不用 strict_types)下,把字符串 "5" 传给 int 类型的参数是允许的。 | «是» Пояснение: 弱类型模式下,字符串 '5' 可以被隐式转换为整数 5 并传给 int 类型的参数。
Raw```json ⏎ {"answer": "是", "解释": "弱类型模式下,字符串 '5' 可以被隐式转换为整数 5 并传给 int 类型的参数。"} ⏎ ``` | верно | Coercive typing приводит "5" к 5; strict_types=1 требует точного типа. |
T06-L1 0.29 c | OOP:类与继承 | PHP 支持构造函数属性提升(promotion):public function __construct(private int $x) {}。 | «是» Пояснение: PHP 8.0 引入了构造函数属性提升,允许在构造函数参数中直接声明属性修饰符以自动创建同名属性。
Raw{"answer": "是", "解释": "PHP 8.0 引入了构造函数属性提升,允许在构造函数参数中直接声明属性修饰符以自动创建同名属性。"} | верно | С PHP 8.0 параметр с модификатором создаёт свойство и присваивание. |
T06-L2 0.21 c | OOP:类与继承 | 哪个关键字禁止在子类中重写方法? | «final» Пояснение: final 关键字用于禁止子类重写方法或继承类。
Raw{"answer": "final", "解释": "final 关键字用于禁止子类重写方法或继承类。"} | верно | final. |
T06-L3 0.21 c | OOP:类与继承 | 声明为 final 的方法不能在子类中重写。 | «是» Пояснение: 在 PHP 中,声明为 final 的方法确实不能在子类中重写。
Raw{"answer": "是", "解释": "在 PHP 中,声明为 final 的方法确实不能在子类中重写。"} | верно | final запрещает переопределение метода и наследование класса. |
T06-L4 0.37 c | OOP:类与继承 | 父类中 private 可见性的属性在子类中可以访问。 | «否» Пояснение: 在PHP中,private 属性的作用域仅限于定义它的类,子类不能直接访问或继承父类的 private 属性。
Raw{"answer": "否", "解释": "在PHP中,private 属性的作用域仅限于定义它的类,子类不能直接访问或继承父类的 private 属性。"} | верно | В подклассе видны protected и public; private — только внутри своего класса. |
T06-L5 0.37 c | OOP:类与继承 | get_class(new class {}) 返回什么?请回答 NUL 字节之前的部分(不含文件路径)。 | «class@anonymous» Пояснение: 匿名类的 get_class() 返回 'class@anonymous' 加上文件名和行号信息。
Raw{"answer": "class@anonymous", "解释": "匿名类的 get_class() 返回 'class@anonymous' 加上文件名和行号信息。"} | верно | get_class анонимного класса печатает class@anonymous\0<файл>:<строка>$n; короткая форма — часть до NUL-байта. Проверено php -r (hex). |
T06-L6 0.35 c | OOP:类与继承 | 父类的 private 方法不属于继承契约:子类可以用任意可见性声明同名方法。 | «是» Пояснение: 父类的 private 方法对子类不可见,因此在子类中定义同名方法时不受可见性限制,可以使用 public、protected 或 private。
Raw{"answer": "是", "解释": "父类的 private 方法对子类不可见,因此在子类中定义同名方法时不受可见性限制,可以使用 public、protected 或 private。"} | верно | private-члены не наследуются — правила совместимости подписей не действуют. |
T06-L7 0.31 c | OOP:类与继承 | 魔术方法 __get() 只会在访问不存在的属性时被调用。 | «是» Пояснение: __get() 只在访问一个非公开或不存在的属性时才会被调用。
Raw```json ⏎ {"answer": "是", "解释": "__get() 只在访问一个非公开或不存在的属性时才会被调用。"} ⏎ ``` | неверно верный: «否» | __get срабатывает и для существующих, но недоступных (private/protected извне). |
T06-L8 0.33 c | OOP:类与继承 | 对 readonly 属性重复赋值会抛出什么——Exception 还是 Error? | «error» Пояснение: readonly 属性重复赋值时,PHP 会抛出 TypeError 或 Error,而不是 Exception。
Raw```json ⏎ { ⏎ "answer": "Error", ⏎ "解释": "readonly 属性重复赋值时,PHP 会抛出 TypeError 或 Error,而不是 Exception。" ⏎ } ⏎ ``` | верно | Error (readonly с 8.1); оговорка: в __clone() переинициализация допустима (8.3+). |
T07-L1 0.23 c | 接口、trait 与 enum | 接口可以声明常量。 | «是» Пояснение: PHP 接口可以定义常量,且这些常量默认为 public 且不可修改。
Raw{"answer": "是", "解释": "PHP 接口可以定义常量,且这些常量默认为 public 且不可修改。"} | верно | Константы интерфейса наследуются реализациями. |
T07-L2 0.23 c | 接口、trait 与 enum | 哪个运算符用于检查对象是否为某个类或接口的实例? | «instanceof» Пояснение: instanceof 运算符用于检查对象是否属于某个类或实现了某个接口。
Raw{"answer": "instanceof", "解释": "instanceof 运算符用于检查对象是否属于某个类或实现了某个接口。"} | верно | instanceof. |
T07-L3 0.39 c | 接口、trait 与 enum | 接口可以声明静态方法。 | «是» Пояснение: PHP 7.1 起,接口中可以声明静态方法,但实现类中该静态方法必须是 public 且不能是 abstract。
Raw{"answer": "是", "解释": "PHP 7.1 起,接口中可以声明静态方法,但实现类中该静态方法必须是 public 且不能是 abstract。"} | верно | Реализация обязана дать статический метод с той же сигнатурой. |
T07-L4 0.23 c | 接口、trait 与 enum | instanceof 运算符只检查类的继承:它不考虑接口。 | «否» Пояснение: instanceof 运算符既检查类的继承,也检查对象是否实现了特定的接口。
Raw{"answer": "否", "解释": "instanceof 运算符既检查类的继承,也检查对象是否实现了特定的接口。"} | верно | instanceof возвращает true и для интерфейсов объекта. |
T07-L5 0.68 c | 接口、trait 与 enum | 接口方法可以像 trait 方法一样带有默认实现。 | «否» Пояснение: PHP 的接口方法通常只能是抽象的(无实现),只有 static 方法或 default 常量可以有定义,不能像 trait 那样为普通实例方法提供默认实现(除非使用 PHP 8.1 的只读属性或特定特性,但标准接口方法本身不支持默认实现)。
Raw{"answer": "否", "解释": "PHP 的接口方法通常只能是抽象的(无实现),只有 static 方法或 default 常量可以有定义,不能像 trait 那样为普通实例方法提供默认实现(除非使用 PHP 8.1 的只读属性或特定特性,但标准接口方法本身不支持默认实现)。"} | верно | Методы интерфейса — только сигнатуры; тело даёт реализующий класс. |
T07-L6 0.32 c | 接口、trait 与 enum | 抽象类中抽象方法的可见性可以是 protected。 | «是» Пояснение: 抽象方法可以是 private、protected 或 public,取决于设计需求。
Raw{"answer": "是", "解释": "抽象方法可以是 private、protected 或 public,取决于设计需求。"} | верно | В абстрактном классе — любая видимость; в интерфейсе — только public. |
T07-L7 0.32 c | 接口、trait 与 enum | 对于 enum Foo { case A; case B; case C; },Foo::cases() 返回多少个元素? | «3» Пояснение: enum 定义了三个 case,Foo::cases() 返回所有 case 组成的数组,共 3 个元素。
Raw{"answer": 3, "解释": "enum 定义了三个 case,Foo::cases() 返回所有 case 组成的数组,共 3 个元素。"} | верно | Статический метод cases(): 3. |
T07-L8 0.29 c | 接口、trait 与 enum | trait 可以声明常量。 | «是» Пояснение: PHP 中 Trait 允许声明常量,这些常量可以在使用该 Trait 的类中直接访问。
Raw{"answer": "是", "解释": "PHP 中 Trait 允许声明常量,这些常量可以在使用该 Trait 的类中直接访问。"} | верно | С PHP 8.2 трейты могут объявлять константы (RFC constants_in_traits); до 8.2 — нет. |
T08-L1 0.25 c | 异常与错误 | Throwable 接口是 Exception 和 Error 的共同祖先。 | «是» Пояснение: 在 PHP 中,Throwable 接口是 Exception 和 Error 的共同父接口,用于捕获异常和错误。
Raw{"answer": "是", "解释": "在 PHP 中,Throwable 接口是 Exception 和 Error 的共同父接口,用于捕获异常和错误。"} | верно | Иерархия с PHP 7: Throwable → Exception и Throwable → Error. |
T08-L2 0.29 c | 异常与错误 | catch (Exception $e) 块也能捕获 TypeError,因为 TypeError 最终继承自 Exception。 | «否» Пояснение: 在 PHP 7 中,TypeError 继承自 Error,而非 Exception。
Raw{"answer": "否", "解释": "在 PHP 7 中,TypeError 继承自 Error,而非 Exception。"} | верно | TypeError наследуется от Error; catch (Exception) его не ловит. |
T08-L3 0.29 c | 异常与错误 | @ 运算符也能抑制异常。 | «否» Пояснение: @ 运算符只抑制错误(warnings, notices 等),而不会抑制异常(exceptions)。
Raw```json ⏎ {"answer": "否", "解释": "@ 运算符只抑制错误(warnings, notices 等),而不会抑制异常(exceptions)。"} ⏎ ``` | верно | @ глушит диагностику (warnings/notices), исключения не перехватывает. |
T08-L4 0.33 c | 异常与错误 | intdiv(5, 0) 会抛出哪个错误类? | «divisionbyzeroerror» Пояснение: PHP 8.0+ 中 intdiv 除数为 0 时抛出 DivisionByZeroError。
Raw{"answer": "DivisionByZeroError", "解释": "PHP 8.0+ 中 intdiv 除数为 0 时抛出 DivisionByZeroError。"} | верно | DivisionByZeroError (иерархия Error, не Exception); php-грейдер объективен. |
T08-L5 0.47 c | 异常与错误 | 只有当异常被 catch 块捕获时,finally 块才会执行。 | «否» Пояснение: finally 块无论是否发生异常都会被执行,即使异常未被捕获,finally 也会先于程序结束而执行。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "finally 块无论是否发生异常都会被执行,即使异常未被捕获,finally 也会先于程序结束而执行。" ⏎ } ⏎ ``` | верно | Наоборот: finally выполняется всегда — даже когда исключение не поймано и уходит выше. Проверено php -r. |
T08-L6 0.59 c | 异常与错误 | 在 finally 块内抛出的异常对 try 块的结果没有任何影响。 | «是» Пояснение: 在 finally 块中抛出的异常会覆盖 try 块中原本返回或抛出的异常,但不会改变 try 块内部代码的执行结果(如变量状态),而是作为最终抛出的异常。
Raw{"answer": "是", "解释": "在 finally 块中抛出的异常会覆盖 try 块中原本返回或抛出的异常,但不会改变 try 块内部代码的执行结果(如变量状态),而是作为最终抛出的异常。"} | неверно верный: «否» | Исключение из finally перекрывает исходное и уходит вместо него. |
T08-L7 0.27 c | 异常与错误 | 表达式 (bool) new Exception('x') 返回什么? | «是» Пояснение: new Exception('x') 是一个对象,将对象转换为布尔值时返回 true。
Raw{"answer": "是", "解释": "new Exception('x') 是一个对象,将对象转换为布尔值时返回 true。"} | верно | Любой объект при приведении к bool — true. Формы ответа: true или да. |
T08-L8 0.33 c | 异常与错误 | 通过 register_shutdown_function() 注册的函数会在调用 exit 时执行。 | «是» Пояснение: PHP 会在脚本结束(包括正常结束、调用 exit 或 die)时执行由 register_shutdown_function 注册的函数。
Raw{"answer": "是", "解释": "PHP 会在脚本结束(包括正常结束、调用 exit 或 die)时执行由 register_shutdown_function 注册的函数。"} | верно | exit завершает скрипт, но shutdown-функции отрабатывают. |
T09-L1 0.58 c | 命名空间与自动加载 | use App\Service\Mailer; 这条语句本身就会加载包含该类的文件。 | «否» Пояснение: use 语句只是给类设置一个别名,真正的文件加载在实例化或引用该类的时刻由自动加载机制(autoload)完成,而不是 use 语句本身。
Raw```json ⏎ {"answer": "否", "解释": "use 语句只是给类设置一个别名,真正的文件加载在实例化或引用该类的时刻由自动加载机制(autoload)完成,而不是 use 语句本身。"} ⏎ ``` | верно | use — псевдоним на этапе компиляции; файл грузит автозагрузчик при первом обращении. |
T09-L2 0.34 c | 命名空间与自动加载 | 要导入函数(而不是类),use 后面写哪个词:function 还是 const? | «function» Пояснение: 在 PHP 中,导入函数使用 use function 语法,导入常量使用 use const 语法。
Raw{"answer": "function", "解释": "在 PHP 中,导入函数使用 use function 语法,导入常量使用 use const 语法。"} | верно | use function ...; (и use const для констант). |
T09-L3 0.36 c | 命名空间与自动加载 | 在 PSR-4 映射 «App\ → src/» 下,类 App\Controller\Api\UserController 会放进哪个文件(相对 src/ 的路径)? | «controller/api/usercontroller.php» Пояснение: PSR-4 将命名空间层级直接映射为子目录,剩余类名作为文件名。
Raw{"answer": "Controller/Api/UserController.php", "解释": "PSR-4 将命名空间层级直接映射为子目录,剩余类名作为文件名。"} | верно | Остаток имени после префикса, \ → /. |
T09-L4 0.31 c | 命名空间与自动加载 | 引入 vendor/autoload.php 会通过 spl_autoload_register() 注册自动加载器。 | «是» Пояснение: Composer 生成的 autoload.php 内部会调用 spl_autoload_register 注册自动加载器。
Raw{"answer": "是", "解释": "Composer 生成的 autoload.php 内部会调用 spl_autoload_register 注册自动加载器。"} | верно | Composer ставит автозагрузчик именно на spl_autoload_register. |
T09-L5 0.21 c | 命名空间与自动加载 | 魔术常量 __NAMESPACE__ 包含当前命名空间的名称。 | «是» Пояснение: 魔术常量 __NAMESPACE__ 确实用于获取当前命名空间的名称。
Raw{"answer": "是", "解释": "魔术常量 __NAMESPACE__ 确实用于获取当前命名空间的名称。"} | верно | В корневом пространстве — пустая строка. |
T09-L6 0.37 c | 命名空间与自动加载 | 在 new 中,非限定类名(不带前导 \)会从全局根开始解析。 | «否» Пояснение: 在 PHP 中,new 语句中的非限定类名(不带前导 \)首先会在当前命名空间中查找,而不是直接从全局根开始解析。
Raw{"answer": "否", "解释": "在 PHP 中,new 语句中的非限定类名(不带前导 \)首先会在当前命名空间中查找,而不是直接从全局根开始解析。"} | верно | Резолвится относительно текущего namespace (с учётом импортов). |
T09-L7 0.5 c | 命名空间与自动加载 | 在 PSR-4 映射 «App\ → src/» 下,类 App\Model\User 位于文件 src/Model/User.php。 | «是» Пояснение: PSR-4 要求命名空间的子部分对应目录,类名对应文件名,App\Model\User 映射为 src/Model/User.php 符合规范。
Raw```json ⏎ {"answer": "是", "解释": "PSR-4 要求命名空间的子部分对应目录,类名对应文件名,App\\Model\\User 映射为 src/Model/User.php 符合规范。"} ⏎ ``` | верно | Остаток имени после префикса переносится в путь как есть. |
T09-L8 0.43 c | 命名空间与自动加载 | use 语句可以写在函数体内——该导入只对这个函数生效。 | «否» Пояснение: 在 PHP 中,use 语句是编译期指令,通常位于命名空间声明之后、类定义之前,不能写在函数体内。
Raw{"answer": "否", "解释": "在 PHP 中,use 语句是编译期指令,通常位于命名空间声明之后、类定义之前,不能写在函数体内。"} | верно | use внутри тела функции — parse error; импорты файловые и компиляционные. |
T10-L1 0.35 c | 引用与作用域 | 数组在赋值时是复制,而不是按引用传递。 | «是» Пояснение: PHP 数组在赋值时采用写时复制(Copy-On-Write)机制,逻辑上表现为值传递而非引用传递。
Raw{ ⏎ "answer": "是", ⏎ "解释": "PHP 数组在赋值时采用写时复制(Copy-On-Write)机制,逻辑上表现为值传递而非引用传递。" ⏎ } | верно | Присваивание массива — копия (в движке — copy-on-write). |
T10-L2 0.26 c | 引用与作用域 | 下面代码输出什么:$a = [1, 2]; $b = $a; $b[] = 3; echo count($a); | «2» Пояснение: PHP 中数组默认是值类型,修改 $b 不会影响 $a。
Raw{"answer": 2, "解释": "PHP 中数组默认是值类型,修改 $b 不会影响 $a。"} | верно | Присваивание — копия: в $a по-прежнему 2 элемента. |
T10-L3 0.43 c | 引用与作用域 | 在函数内部,不通过 global、$GLOBALS 或参数传递,就无法访问全局作用域的用户变量。 | «是» Пояснение: 在 PHP 中,函数内部访问全局变量确实需要使用 global、$GLOBALS 或通过参数传递,否则只能访问函数内的局部变量。
Raw```json ⏎ { ⏎ "answer": "对", ⏎ "解释": "在 PHP 中,函数内部访问全局变量确实需要使用 global、$GLOBALS 或通过参数传递,否则只能访问函数内的局部变量。" ⏎ } ⏎ ``` | верно | Область видимости функций изолирована; исключение — суперглобалы ($_GET и др.). |
T10-L4 0.27 c | 引用与作用域 | 在函数内 unset($GLOBALS['x']) 只对该函数删除这个全局变量。 | «否» Пояснение: unset($GLOBALS['x']) 会直接删除全局作用域中的变量,影响所有能访问该变量的地方。
Raw{"answer": "否", "解释": "unset($GLOBALS['x']) 会直接删除全局作用域中的变量,影响所有能访问该变量的地方。"} | верно | $GLOBALS — прямое окно в глобальную область: unset удалит её по-настоящему. |
T10-L5 0.24 c | 引用与作用域 | 下面代码输出什么:function inc(&$x) { $x++; } $n = 5; inc($n); echo $n; | «6» Пояснение: 函数通过引用传递参数,修改了原变量的值。
Raw{"answer": 6, "解释": "函数通过引用传递参数,修改了原变量的值。"} | верно | Ссылка меняет оригинал: 6. |
T10-L6 0.31 c | 引用与作用域 | 按值遍历数组的 foreach 操作的是“活”数组:循环内对数组的修改在同一个遍历过程中可见。 | «否» Пояснение: foreach 默认按值遍历(pass-by-value),循环内对数组的修改不会在同一个遍历过程中立即可见。
Raw{"answer": "否", "解释": "foreach 默认按值遍历(pass-by-value),循环内对数组的修改不会在同一个遍历过程中立即可见。"} | верно | По значению foreach итерирует копию-снимок. |
T10-L7 0.27 c | 引用与作用域 | 静态属性在每个实例中各自独立:一个对象中的修改对其他对象不可见。 | «否» Пояснение: 静态属性属于类而非实例,所有实例共享同一份数据,修改会对其他对象可见。
Raw{"answer": "否", "解释": "静态属性属于类而非实例,所有实例共享同一份数据,修改会对其他对象可见。"} | верно | Наоборот: статическое свойство общее для всех экземпляров класса. Проверено php -r. |
T10-L8 0.3 c | 引用与作用域 | 数组可以用布尔值 true 作为键,并且它会以 bool 类型保存。 | «否» Пояснение: 在 PHP 中,布尔值 true 作为数组键时会被强制转换为整数 1。
Raw{"answer": "否", "解释": "在 PHP 中,布尔值 true 作为数组键时会被强制转换为整数 1。"} | верно | Булев ключ приводится к int: true → 1, false → 0. |
T11-L1 0.37 c | 生成器、迭代器与 SPL | 生成器内部可以使用带值的 return,该值可以通过 $gen->getReturn() 取到。 | «是» Пояснение: PHP 生成器(Generator)支持使用 `return` 语句返回一个值,该值可以通过 Generator 对象的 `getReturn()` 方法获取。
Raw{ ⏎ "answer": "是", ⏎ "解释": "PHP 生成器(Generator)支持使用 `return` 语句返回一个值,该值可以通过 Generator 对象的 `getReturn()` 方法获取。" ⏎ } | верно | return-значение генератора доступно через getReturn() после прохода. |
T11-L2 0.37 c | 生成器、迭代器与 SPL | 已经遍历完的生成器可以通过 rewind() 倒回并重新遍历。 | «否» Пояснение: 生成器是一次性的,无法通过 rewind() 重新遍历;只有实现了 Traversable 接口的类(如 ArrayIterator)才支持 rewind。
Raw{"answer": "否", "解释": "生成器是一次性的,无法通过 rewind() 重新遍历;只有实现了 Traversable 接口的类(如 ArrayIterator)才支持 rewind。"} | верно | Генератор одноразовый: rewind после начала итерации бросает Exception. |
T11-L3 0.28 c | 生成器、迭代器与 SPL | yield from 语法会把遍历委托给另一个生成器或可迭代对象。 | «是» Пояснение: yield from 用于委托迭代,可展开另一个生成器或可迭代对象。
Raw{"answer": "是", "解释": "yield from 用于委托迭代,可展开另一个生成器或可迭代对象。"} | верно | yield from проксирует значения, ключи и return-значение внутреннего генератора. |
T11-L4 0.26 c | 生成器、迭代器与 SPL | 对于 function g() { yield 1; },get_class(g()) 返回什么? | «generator» Пояснение: yield 关键字使函数返回一个 Generator 对象,其类名为 Generator。
Raw{"answer": "Generator", "解释": "yield 关键字使函数返回一个 Generator 对象,其类名为 Generator。"} | верно | Функция с yield возвращает Generator. |
T11-L5 0.3 c | 生成器、迭代器与 SPL | count(iterator_to_array((function () { yield from [1, 2, 3]; })())) 返回多少个元素? | «3» Пояснение: iterator_to_array 将生成器转换为数组 [1, 2, 3],count 返回其元素个数 3。
Raw{"answer": 3, "解释": "iterator_to_array 将生成器转换为数组 [1, 2, 3],count 返回其元素个数 3。"} | верно | yield from делегирует все 3 элемента. |
T11-L6 0.27 c | 生成器、迭代器与 SPL | SplStack 类实现的是 FIFO 队列。 | «否» Пояснение: SplStack 实现的是 LIFO(后进先出)栈,而不是 FIFO(先进先出)队列。
Raw{"answer": "否", "解释": "SplStack 实现的是 LIFO(后进先出)栈,而不是 FIFO(先进先出)队列。"} | верно | SplStack — стек LIFO; очередь FIFO — SplQueue. |
T11-L7 0.25 c | 生成器、迭代器与 SPL | ArrayIterator 可以包装数组,并通过 Iterator 接口遍历它。 | «是» Пояснение: ArrayIterator 实现了 Iterator 接口,可以将普通数组转换为可迭代对象。
Raw{"answer": "是", "解释": "ArrayIterator 实现了 Iterator 接口,可以将普通数组转换为可迭代对象。"} | верно | Объектная обёртка над массивом. |
T11-L8 0.23 c | 生成器、迭代器与 SPL | ArrayObject 类的对象不能用 foreach 遍历。 | «否» Пояснение: ArrayObject 实现了 Traversable 接口,因此可以用 foreach 遍历。
Raw{"answer": "否", "解释": "ArrayObject 实现了 Traversable 接口,因此可以用 foreach 遍历。"} | верно | ArrayObject реализует IteratorAggregate — foreach по нему работает. |
T12-L1 0.25 c | 配置与安全 | password_hash() 会自动生成盐(salt)——不需要单独传盐。 | «是» Пояснение: password_hash() 默认自动生成随机盐。
Raw```json ⏎ {"answer": "是", "解释": "password_hash() 默认自动生成随机盐。"} ⏎ ``` | верно | Соль встраивается в строку результата; параметр salt устарел. |
T12-L2 0.73 c | 配置与安全 | 在 PHP 8 中,PASSWORD_DEFAULT 算法是自动加盐的 md5。 | «否» Пояснение: 在 PHP 8 中,PASSWORD_DEFAULT 对应的算法是 password_hash() 默认采用的 bcrypt(cost 为 10),而不是 md5。md5 不是自动加盐的,也不安全,而 bcrypt 会自动生成加盐值(salt)并支持哈希迭代。
Raw```json ⏎ {"answer": "否", "解释": "在 PHP 8 中,PASSWORD_DEFAULT 对应的算法是 password_hash() 默认采用的 bcrypt(cost 为 10),而不是 md5。md5 不是自动加盐的,也不安全,而 bcrypt 会自动生成加盐值(salt)并支持哈希迭代。"} ⏎ ``` | верно | PASSWORD_DEFAULT — bcrypt; md5 для паролей непригоден (перебирается массово). |
T12-L3 0.24 c | 配置与安全 | password_verify('secret', password_hash('secret', PASSWORD_DEFAULT)) 返回什么? | «是» Пояснение: password_verify 验证密码与哈希匹配时返回 true。
Raw{"answer": "是", "解释": "password_verify 验证密码与哈希匹配时返回 true。"} | верно | Соль и хеш в одной строке: true (форма ответа: true или да). |
T12-L4 0.41 c | 配置与安全 | strip_tags() 函数能防 SQL 注入。 | «否» Пояснение: strip_tags() 用于移除 HTML 标签,防止 XSS,但无法处理 SQL 特殊字符(如单引号、分号),不能防 SQL 注入。
Raw{"answer": "否", "解释": "strip_tags() 用于移除 HTML 标签,防止 XSS,但无法处理 SQL 特殊字符(如单引号、分号),不能防 SQL 注入。"} | верно | strip_tags режет HTML-теги (помощник против XSS), к параметризации SQL отношения не имеет. |
T12-L5 0.33 c | 配置与安全 | session_regenerate_id() 函数用于在用户登录时防范会话固定(session fixation)。 | «是» Пояснение: session_regenerate_id() 通过生成新的会话 ID 来防止会话固定攻击,通常在用户登录状态变更时调用。
Raw{"answer": "是", "解释": "session_regenerate_id() 通过生成新的会话 ID 来防止会话固定攻击,通常在用户登录状态变更时调用。"} | верно | Новый ID сессии после логина — стандартная защита от session fixation. |
T12-L6 0.31 c | 配置与安全 | 哪个内置函数返回 SAPI 的名称(例如 cli)? | «php_sapi_name» Пояснение: php_sapi_name() 函数返回当前 SAPI 的名称,例如 'cli' 或 'apache2handler'。
Raw{"answer": "php_sapi_name", "解释": "php_sapi_name() 函数返回当前 SAPI 的名称,例如 'cli' 或 'apache2handler'。"} | верно | php_sapi_name(). |
T12-L7 0.43 c | 配置与安全 | session_destroy() 删除服务器端的会话数据,但不会删除用户浏览器中的 cookie。 | «是» Пояснение: session_destroy() 确实删除服务器端会话数据,但用户浏览器中的 PHPSESSID cookie 需要手动通过 setcookie() 删除。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "session_destroy() 确实删除服务器端会话数据,但用户浏览器中的 PHPSESSID cookie 需要手动通过 setcookie() 删除。" ⏎ } ⏎ ``` | верно | Удаление cookie — отдельный шаг через setcookie с истёкшим сроком. |
T12-L8 0.39 c | 配置与安全 | 不调用 session_start(),$_SESSION 数组也会自动加载会话数据。 | «否» Пояснение: 必须调用 session_start() 来启动或恢复会话,并加载 $_SESSION 中的会话数据。
Raw```json ⏎ {"answer": "否", "解释": "必须调用 session_start() 来启动或恢复会话,并加载 $_SESSION 中的会话数据。"} ⏎ ``` | верно | Без session_start() данные сессии в массив не загружаются ($_SESSION можно заполнить вручную, но привязки к сессии нет). |
VC-L1 0.23 c | PHP 8.4–8.5 | 函数 array_find() 是在哪个 PHP 版本中引入的? | «8.0» Пояснение: array_find() 是在 PHP 8.0 中引入的。
Raw{"answer": "8.0", "解释": "array_find() 是在 PHP 8.0 中引入的。"} | неверно верный: «8.4» | PHP 8.4 (RFC array_find). |
VC-L2 0.23 c | PHP 8.4–8.5 | 属性钩子(property hooks,直接在属性声明里写 get/set)进入了 PHP 8.4。 | «是» Пояснение: 属性钩子是 PHP 8.4 引入的新特性。
Raw```json ⏎ {"answer": "是", "解释": "属性钩子是 PHP 8.4 引入的新特性。"} ⏎ ``` | верно | Property hooks — PHP 8.4 (ноябрь 2024). |
VC-L3 0.45 c | PHP 8.4–8.5 | 非对称可见性(public private(set) string $name)出现在 PHP 8.4。 | «是» Пояснение: PHP 8.4 支持使用 private(set) 来实现非对称可见性,允许外部读取但只有类内部可以设置属性的值。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "PHP 8.4 支持使用 private(set) 来实现非对称可见性,允许外部读取但只有类内部可以设置属性的值。" ⏎ } ⏎ ``` | верно | Asymmetric visibility v2 — PHP 8.4. |
VC-L4 0.27 c | PHP 8.4–8.5 | 属性 #[\NoDiscard] 最早出现在哪个 PHP 版本?请回答版本号。 | «8.4» Пояснение: #[\NoDiscard] 属性是在 PHP 8.4 中引入的。
Raw{"answer": "8.4", "解释": "#[\\NoDiscard] 属性是在 PHP 8.4 中引入的。"} | неверно верный: «8.5» | #[\NoDiscard] — PHP 8.5 (marking return values as important). |
VC-L5 0.24 c | PHP 8.4–8.5 | 管道运算符 |> 最早出现在哪个 PHP 版本?请回答版本号。 | «7.0» Пояснение: 管道运算符在 PHP 7.0 中首次引入。
Raw{"answer": "7.0", "解释": "管道运算符在 PHP 7.0 中首次引入。"} | неверно верный: «8.5» | Pipe operator — PHP 8.5 (2025). |
VC-L6 0.24 c | PHP 8.4–8.5 | clone-with 语法 clone($obj, ['x' => 1]) 是在哪个 PHP 版本中出现的?请回答版本号。 | «8.4» Пояснение: clone-with 语法是在 PHP 8.4 中引入的。
Raw```json ⏎ {"answer": "8.4", "解释": "clone-with 语法是在 PHP 8.4 中引入的。"} ⏎ ``` | неверно верный: «8.5» | Clone with v2 — PHP 8.5. |
VC-L7 0.52 c | PHP 8.4–8.5 | 函数 array_first() 和 array_last() 是在哪个 PHP 版本中引入的? | «php 8.4» Пояснение: array_first() 和 array_last() 是 PHP 8.4 中引入的新函数,用于替代之前使用 reset() 和 end() 或其他方式获取数组第一个和最后一个元素的方法。
Raw```json ⏎ { ⏎ "answer": "PHP 8.4", ⏎ "解释": "array_first() 和 array_last() 是 PHP 8.4 中引入的新函数,用于替代之前使用 reset() 和 end() 或其他方式获取数组第一个和最后一个元素的方法。" ⏎ } ⏎ ``` | неверно верный: «8.5» | PHP 8.5. |
VC-L8 0.27 c | PHP 8.4–8.5 | 截至 2026-11-07,RFC Partial Function Application v2 被接受进入哪个 PHP 版本?请回答版本号。 | «8.5» Пояснение: RFC Partial Function Application v2 被接受进入 PHP 8.5。
Raw{"answer": "8.5", "解释": "RFC Partial Function Application v2 被接受进入 PHP 8.5。"} | неверно верный: «8.6» | PFA v2 принят 05.12.2025 (33-0-0), реализован в PHP 8.6. |
VF-L1 0.38 c | PHP:8.6+ 与未来 | 截至 2026-11-07,RFC clamp_v2(函数 clamp())在哪个 PHP 版本中实现?请回答版本号。 | «8.4.0» Пояснение: RFC clamp_v2 在 PHP 8.4 中正式引入并实现了新的 clamp() 函数。
Raw{ ⏎ "answer": "8.4.0", ⏎ "解释": "RFC clamp_v2 在 PHP 8.4 中正式引入并实现了新的 clamp() 函数。" ⏎ } | неверно верный: «8.6» | По данным владельца (wiki.php.net/rfc): clamp_v2 — 8.6; clamp() в 8.5.11 отсутствует (косвенное подтверждение). Дата-якорь делает клетку монотонной. |
VF-L2 0.27 c | PHP:8.6+ 与未来 | 截至 2026-11-07,RFC Context Managers v2 已被 PHP 接受。 | «否» Пояснение: RFC Context Managers v2 尚未被 PHP 接受。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "RFC Context Managers v2 尚未被 PHP 接受。" ⏎ } ⏎ ``` | верно | На 06.11.2026 — в обсуждении (создан 2026-10-23); не принят. |
VF-L3 0.31 c | PHP:8.6+ 与未来 | RFC Bound-Erased Generic Types(泛型)已于 2026 年被拒绝。 | «是» Пояснение: PHP RFC 泛型(Bound-Erased Generic Types)已在 2026 年的投票中被拒绝。
Raw{"answer": "是", "解释": "PHP RFC 泛型(Bound-Erased Generic Types)已在 2026 年的投票中被拒绝。"} | верно | Голосование завершилось 2026-06-28: отклонён (wiki.php.net/rfc). |
VF-L4 0.37 c | PHP:8.6+ 与未来 | 截至 2026-11-07,默认启用多线程(ZTS)的 RFC 已在 PHP 中被接受。 | «否» Пояснение: PHP 默认仍然使用单线程构建(NTS),虽然支持 ZTS,但 ZTS 并非默认启用。
Raw{"answer": "否", "解释": "PHP 默认仍然使用单线程构建(NTS),虽然支持 ZTS,但 ZTS 并非默认启用。"} | верно | Такого принятого RFC нет на дату якоря; якорь делает клетку монотонной — при принятии RFC позже клетка не перевернётся. |
VF-L5 0.33 c | PHP:8.6+ 与未来 | PHP 8.5 仍然没有泛型(参数化类型)。 | «是» Пояснение: PHP 语言本身尚未原生支持泛型,通常通过后缀命名约定或 Union Types 模拟实现。
Raw{ ⏎ "answer": "是", ⏎ "解释": "PHP 语言本身尚未原生支持泛型,通常通过后缀命名约定或 Union Types 模拟实现。" ⏎ } | верно | Generics в PHP отсутствуют; отрицательный контроль (не путать с C#/Java). |
VF-L6 1.6 c | PHP:8.6+ 与未来 | 截至 2026-11-07,PHP 的最新稳定版本是 8.5,PHP 8.6 尚未发布(GA 为 2026-11-19)。 | «否» Пояснение: PHP 8.5 计划于 2025 年 11 月发布,而 PHP 8.6 计划于 2026 年 11 月发布,因此截至 2026-11-07 最新稳定版应为 8.5,但题目中 8.6 的 GA 日期为 2026-11-19 符合规律,然而问题在于 PHP 版本通常每年 11 月发布,2026-11-07 时 8.6 尚未 GA 是对的,但 8.5 在 2025-11 已发布,所以说法整体正确?需仔细:PHP 8.4 是 2024-11,8.5 是 2025-11,8.6 是 2026-11。截至 2026-11-07,8.6 还没到 11-19 的 GA,所以最新稳定是 8.5,陈述正确。
Raw{"answer": "否", "解释": "PHP 8.5 计划于 2025 年 11 月发布,而 PHP 8.6 计划于 2026 年 11 月发布,因此截至 2026-11-07 最新稳定版应为 8.5,但题目中 8.6 的 GA 日期为 2026-11-19 符合规律,然而问题在于 PHP 版本通常每年 11 月发布,2026-11-07 时 8.6 尚未 GA 是对的,但 8.5 在 2025-11 已发布,所以说法整体正确?需仔细:PHP 8.4 是 2024-11,8.5 是 2025-11,8.6 是 2026-11。截至 2026-11-07,8.6 还没到 11-19 的 GA,所以最新稳定是 8.5,陈述正确。"} | неверно верный: «是» | 8.5 — релиз осени 2025; 8.6 GA 19.11.2026 (wiki.php.net/todo/php86). Дата снимка — 06.11.2026. |
VF-L7 0.33 c | PHP:8.6+ 与未来 | PHP 6 分支从未发布:PHP 5.6 之后直接就是 PHP 7.0。 | «是» Пояснение: PHP 6 分支在开发过程中被取消,版本号从 5.6 直接跳到了 7.0。
Raw{"answer": "是", "解释": "PHP 6 分支在开发过程中被取消,版本号从 5.6 直接跳到了 7.0。"} | верно | Исторический факт: ветка 6 не была релизнута. |
VF-L8 0.43 c | PHP:8.6+ 与未来 | 向核心添加 #[\Deprecated] 属性的 RFC 已被接受。 | «是» Пояснение: RFC 98182 已被接受,允许向 PHP 核心代码添加 #[\Deprecated] 属性以标记弃用的 API。
Raw{"answer": "是", "解释": "RFC 98182 已被接受,允许向 PHP 核心代码添加 #[\\Deprecated] 属性以标记弃用的 API。"} | верно | #[\Deprecated] — принят, реализован в PHP 8.4. |
T25-L1 0.37 c | 整洁架构 | 整洁架构与洋葱架构的依赖规则:内层对外层一无所知——依赖指向中心。 | «是» Пояснение: 整洁架构与洋葱架构的核心原则是依赖倒置,即外层依赖内层(领域/实体),而内层不依赖外层。
Raw{"answer": "是", "解释": "整洁架构与洋葱架构的核心原则是依赖倒置,即外层依赖内层(领域/实体),而内层不依赖外层。"} | верно | Чистая (Robert C. Martin), луковичная (Jeffrey Palermo) и гексагональная (ports & adapters) — варианты одной идеи: зависимости направлены внутрь, к домену. Слоями в проекте следит deptrac. |
T25-L2 0.57 c | 整洁架构 | 领域实体既不导入 Doctrine 也不导入 Symfony——只用语言本身(最多加标准库)。 | «是» Пояснение: 领域实体应尽量保持独立,避免依赖框架(如 Doctrine/Symfony),以提升可测试性和解耦性,仅依赖语言及标准库是良好的领域驱动设计实践。
Raw{ ⏎ "answer": "是", ⏎ "解释": "领域实体应尽量保持独立,避免依赖框架(如 Doctrine/Symfony),以提升可测试性和解耦性,仅依赖语言及标准库是良好的领域驱动设计实践。" ⏎ } | верно | Изоляция домена от инфраструктуры; deptrac в проекте как раз следит за слоями. |
T25-L3 0.43 c | 整洁架构 | 控制器和 Twig 模板属于业务逻辑层,因为是它们调用用例。 | «否» Пояснение: 控制器和模板属于表示层(表现层),用例协调它们与领域模型交互,而非由它们直接定义业务逻辑。
Raw{"answer": "否", "解释": "控制器和模板属于表示层(表现层),用例协调它们与领域模型交互,而非由它们直接定义业务逻辑。"} | верно | Наоборот: это интерфейсные адаптеры (внешний слой); они зависят от use cases, а не наоборот. |
T25-L4 0.36 c | 整洁架构 | 洋葱架构的最中心是什么? | «实体» Пояснение: 洋葱架构的最核心层是由业务实体组成的,代表了系统的核心领域模型。
Raw{"answer": "实体", "解释": "洋葱架构的最核心层是由业务实体组成的,代表了系统的核心领域模型。"} | неверно верный: «domain model» | Центральное кольцо — Domain Model: сущности и бизнес-правила без зависимостей; далее Domain Services → Application Services → Infrastructure/UI/Tests (Palermo). |
T25-L5 0.39 c | 整洁架构 | 层边界的破坏可以自动捕获:层间依赖分析器(如 deptrac)会在出现禁止的调用时报错。 | «是» Пояснение: deptrac 等工具通过静态分析层间依赖,能在构建或测试阶段自动检测并报告违反架构层边界的调用。
Raw{"answer": "是", "解释": "deptrac 等工具通过静态分析层间依赖,能在构建或测试阶段自动检测并报告违反架构层边界的调用。"} | верно | depfile.yaml в проекте TasK: CI проверяет правила слоёв на каждом пайплайне. |
T25-L6 0.64 c | 整洁架构 | 用例(interactor)可以接受 HTTP 请求或 EntityManager 作为参数——这样更简单。 | «否» Пояснение: 在整洁架构中,Interactor(用例)不应直接依赖基础设施细节如 EntityManager 或 HTTP 请求,而应依赖更通用的接口或依赖注入的仓储/服务,以保持用例逻辑的纯粹性和可测试性。
Raw{"answer": "否", "解释": "在整洁架构中,Interactor(用例)不应直接依赖基础设施细节如 EntityManager 或 HTTP 请求,而应依赖更通用的接口或依赖注入的仓储/服务,以保持用例逻辑的纯粹性和可测试性。"} | верно | Use case принимает DTO и порты; привязка к HTTP/ORM протекает инфраструктуру во внутренние слои. |
T25-L7 0.37 c | 整洁架构 | 在接口背后隐藏存储机制、并提供聚合/实体集合的组件叫什么? | «仓储(repository)» Пояснение: 仓储模式(Repository Pattern)在接口背后隐藏存储机制,并负责聚合/实体集合的管理。
Raw{"answer": "仓储(Repository)", "解释": "仓储模式(Repository Pattern)在接口背后隐藏存储机制,并负责聚合/实体集合的管理。"} | верно | Repository pattern (DDD/Evans); в проекте — Doctrine-репозитории за портами. |
T25-L8 0.33 c | 整洁架构 | 在整洁架构中,把 PostgreSQL 换成其他数据库只会影响外层——领域和用例保持不变。 | «是» Пояснение: 整洁架构的设计原则就是将外部细节(如数据库)与核心业务逻辑隔离。
Raw```json ⏎ {"answer": "是", "解释": "整洁架构的设计原则就是将外部细节(如数据库)与核心业务逻辑隔离。"} ⏎ ``` | верно | Следствие правила зависимостей: инфраструктура взаимозаменяема. |
T26-L1 0.31 c | DDD | 在 DDD 中,聚合(aggregate)只是数据库表的另一个名字。 | «否» Пояснение: 聚合是领域模型中的一致性和完整性边界,而数据库表是存储结构,二者概念不同。
Raw{"answer": "否", "解释": "聚合是领域模型中的一致性和完整性边界,而数据库表是存储结构,二者概念不同。"} | верно | Агрегат — кластер объектов с границей согласованности (транзакционной вокруг корня); таблица — деталь хранения. |
T26-L2 0.47 c | DDD | 值对象(Value Object)不可变,按字段值比较,而不是按标识符。 | «是» Пояснение: 值对象的核心特征是不可变性,且两个值对象只要属性值相同即被视为相等,不依赖对象标识符(如内存地址或ID)。
Raw{"answer": "是", "解释": "值对象的核心特征是不可变性,且两个值对象只要属性值相同即被视为相等,不依赖对象标识符(如内存地址或ID)。"} | верно | Классика Evans: Money, Email; равенство структурное. |
T26-L3 0.32 c | DDD | 聚合的唯一外部入口——所有变更必须经过它——叫什么? | «命令» Пояснение: 在领域驱动设计中,命令(Command)是改变聚合状态的唯一外部入口。
Raw{"answer": "命令", "解释": "在领域驱动设计中,命令(Command)是改变聚合状态的唯一外部入口。"} | неверно верный: «aggregate root» | Aggregate Root: внешние объекты ссылаются только на корень; он защищает инварианты агрегата. |
T26-L4 0.39 c | DDD | 在 DDD 中,仓储是针对聚合(其根)声明的,而不是针对每个实体。 | «是» Пояснение: 在 DDD 中,仓储通常针对聚合根(Aggregate Root)声明,而不是针对每一个单独的实体,以确保聚合内实体的一致性。
Raw```json ⏎ {"answer": "是", "解释": "在 DDD 中,仓储通常针对聚合根(Aggregate Root)声明,而不是针对每一个单独的实体,以确保聚合内实体的一致性。"} ⏎ ``` | верно | Репозиторий корня хранит границу согласованности агрегата; вложенные сущности доступны только через корень. |
T26-L5 0.29 c | DDD | 统一语言(ubiquitous language)是开发者和领域专家共享的模型语言。 | «是» Пояснение: 统一语言是 DDD 中确保开发与业务团队沟通一致的核心概念。
Raw{"answer": "是", "解释": "统一语言是 DDD 中确保开发与业务团队沟通一致的核心概念。"} | верно | Evans: язык из требований переходит в имена классов и методов. |
T26-L6 0.54 c | DDD | 哪种边界内部模型和语言一致,而边界外同样的词对应别的模型? | «自然句» Пояснение: 自然句的边界内部遵循特定的语法模型(如主谓宾结构),而边界外(如标点或换行后)同样的词汇可能启动新的语法模型或语义单元。
Raw{"answer": "自然句", "解释": "自然句的边界内部遵循特定的语法模型(如主谓宾结构),而边界外(如标点或换行后)同样的词汇可能启动新的语法模型或语义单元。"} | неверно верный: «bounded context» | Bounded Context; «Заказ» в биллинге и в доставке — разные модели. |
T26-L7 0.49 c | DDD | 贫血模型(只有 getter/setter,逻辑全在服务里)是 DDD 推荐的风格。 | «否» Пояснение: 贫血模型仅封装状态,而DDD推崇富模型(充血模型)将业务逻辑封装在实体内以保持领域层核心地位。
Raw{ ⏎ "answer": "否", ⏎ "解释": "贫血模型仅封装状态,而DDD推崇富模型(充血模型)将业务逻辑封装在实体内以保持领域层核心地位。" ⏎ } | верно | Наоборот: Evans называет анемичность антипаттерном — поведение должно жить в доменных объектах. |
T26-L8 0.44 c | DDD | 限界上下文意味着每个上下文都有自己的模型:同一个概念在不同上下文中是不同的类。 | «是» Пояснение: 在领域驱动设计(DDD)中,限界上下文的核心原则之一就是模型隔离,同一业务概念在不同上下文中可以有完全不同的类定义、属性和行为,以适配各自的业务需求。
Raw{"answer": "是", "解释": "在领域驱动设计(DDD)中,限界上下文的核心原则之一就是模型隔离,同一业务概念在不同上下文中可以有完全不同的类定义、属性和行为,以适配各自的业务需求。"} | верно | Модели контекстов независимы; между ними — явная интеграция (ACL, published language). |
T13-L1 0.33 c | Symfony | Symfony 的 DI 容器中的服务默认是惰性创建的——在首次使用时才实例化。 | «是» Пояснение: Symfony 依赖注入容器默认采用延迟加载机制,只有在首次请求服务时才会进行实例化。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "Symfony 依赖注入容器默认采用延迟加载机制,只有在首次请求服务时才会进行实例化。" ⏎ } ⏎ ``` | верно | Контейнер инстанцирует сервис при первом извлечении; eager-создания по умолчанию нет. |
T13-L2 0.31 c | Symfony | Symfony 的哪条控制台命令会列出所有已注册的路由? | «php bin/console debug:router» Пояснение: 在 Symfony 中,使用 `debug:router` 命令可以列出所有已注册的路由。
Raw{"answer": "php bin/console debug:router", "解释": "在 Symfony 中,使用 `debug:router` 命令可以列出所有已注册的路由。"} | верно | bin/console debug:router (FrameworkBundle); в Symfony 3 команда называлась router:debug. |
T13-L3 0.43 c | Symfony | Symfony 的自动装配(autowiring)需要在 services.yaml 中手动声明每一个服务。 | «否» Пояснение: Symfony 的自动装配通过自动检测和解析依赖,可以在许多情况下自动生成服务定义,不需要手动声明每一个服务。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "Symfony 的自动装配通过自动检测和解析依赖,可以在许多情况下自动生成服务定义,不需要手动声明每一个服务。" ⏎ } ⏎ ``` | верно | Autowire+autoconfigure регистрируют и связывают сервисы автоматически; ручное перечисление — исключение. |
T13-L4 0.31 c | Symfony | Twig 模板会编译成 PHP 类并在请求之间缓存。 | «是» Пояснение: Twig 模板会被编译成 PHP 类,并缓存编译后的模板,以提高性能。
Raw{"answer": "是", "解释": "Twig 模板会被编译成 PHP 类,并缓存编译后的模板,以提高性能。"} | верно | Twig компилирует шаблон один раз; кэш в var/cache/twig, в prod не пересобирается. |
T13-L5 0.44 c | Symfony | 在 Symfony 的 dev 环境中,DI 容器只在被跟踪的文件变化后重建,而不是每个请求都重建。 | «否» Пояснение: 在 dev 环境中,Symfony 的 DI 容器默认是每个请求都会重新编译和重建,而不是仅在文件变化后重建(除非使用特定的缓存或预编译配置)。
Raw{"answer": "否", "解释": "在 dev 环境中,Symfony 的 DI 容器默认是每个请求都会重新编译和重建,而不是仅在文件变化后重建(除非使用特定的缓存或预编译配置)。"} | неверно верный: «是» | Kernel проверяет freshness ресурсов (конфиги, классы); иначе переиспользуется кэш контейнера. |
T13-L6 0.25 c | Symfony | 哪个环境变量决定 Symfony 的活动环境(dev/prod)? | «app_env» Пояснение: Symfony 使用 APP_ENV 环境变量来决定当前活动的环境(如 dev 或 prod)。
Raw{"answer": "APP_ENV", "解释": "Symfony 使用 APP_ENV 环境变量来决定当前活动的环境(如 dev 或 prod)。"} | верно | APP_ENV в .env; APP_DEBUG — отдельный флаг отладки. |
T13-L7 0.29 c | Symfony | 控制器方法可以是 private——Symfony 的路由对类中的任何方法都有效。 | «否» Пояснение: Symfony 控制器方法必须是公共的(public),否则路由系统无法访问它们。
Raw{"answer": "否", "解释": "Symfony 控制器方法必须是公共的(public),否则路由系统无法访问它们。"} | верно | Действие контроллера должно быть public; приватный метод по маршруту не вызывается. |
T13-L8 0.53 c | Symfony | 事件订阅者(EventSubscriber)总是比监听器(listener)更早收到事件,因为接口赋予它们优先级。 | «否» Пояснение: 事件订阅者(EventSubscriber)在接口中没有优先级规定,优先级是通过其订阅的事件配置决定的,和监听器(Listener)一样是根据配置的优先级排序的。
Raw```json ⏎ {"answer": "否", "解释": "事件订阅者(EventSubscriber)在接口中没有优先级规定,优先级是通过其订阅的事件配置决定的,和监听器(Listener)一样是根据配置的优先级排序的。"} ⏎ ``` | верно | Порядок определяет priority, а не тип подписки; приоритеты задаются в getSubscribedEvents() так же, как у слушателей. |
T22-L1 0.46 c | Symfony:安全与表单 | 在现代 Symfony(6.0+)中,认证基于 authenticator 类(AuthenticatorInterface);旧的 guard 体系已被移除。 | «是» Пояснение: 在 Symfony 5.3 中引入了基于 Authenticator 的新认证系统,并在 Symfony 6.0 中正式移除了对旧的 guard 认证体系的支持。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "在 Symfony 5.3 中引入了基于 Authenticator 的新认证系统,并在 Symfony 6.0 中正式移除了对旧的 guard 认证体系的支持。" ⏎ } ⏎ ``` | верно | Guard объявлен устаревшим в 5.3 и удалён в 6.0; в проекте symfony/security-bundle 8.1. |
T22-L2 0.47 c | Symfony:安全与表单 | Symfony 的哪个属性直接在控制器方法上检查角色/权限(没有它就返回 403)? | «#isgranted» Пояснение: Symfony 提供 #[IsGranted] 属性,用于在控制器方法上直接进行角色或权限检查,未通过时抛出 AccessDeniedException 导致 403。
Raw{"answer": "#IsGranted", "解释": "Symfony 提供 #[IsGranted] 属性,用于在控制器方法上直接进行角色或权限检查,未通过时抛出 AccessDeniedException 导致 403。"} | верно | #[IsGranted('ROLE_ADMIN')]; атрибут из symfony/security-http. |
T22-L3 0.51 c | Symfony:安全与表单 | Voter(投票者)是 Symfony 检查对具体对象访问权的机制:isGranted('EDIT', $post)。 | «是» Пояснение: Voter 是 Symfony 安全系统中用于对具体对象检查访问权限的机制,可以通过 isGranted('EDIT', $post) 来检查是否允许执行 EDIT 操作。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "Voter 是 Symfony 安全系统中用于对具体对象检查访问权限的机制,可以通过 isGranted('EDIT', $post) 来检查是否允许执行 EDIT 操作。" ⏎ } ⏎ ``` | верно | VoterInterface->vote(); docs Symfony — Voters. |
T22-L4 0.53 c | Symfony:安全与表单 | 在现代 Symfony(7+)中,验证约束用 PHP 属性声明(#[Assert\NotBlank]);不再支持 doctrine 注解。 | «是» Пояснение: Symfony 从 5.3 开始推荐使用 PHP 属性声明约束,7.0 版本中不再支持 Doctrine 注解,因此这个说法是正确的。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "Symfony 从 5.3 开始推荐使用 PHP 属性声明约束,7.0 版本中不再支持 Doctrine 注解,因此这个说法是正确的。" ⏎ } ⏎ ``` | верно | Докблок-аннотации удалены в Symfony 7.0; стандарт — атрибуты. В проекте symfony/validator 8.1. |
T22-L5 0.3 c | Symfony:安全与表单 | Symfony 表单的 CSRF 保护默认开启:表单在提交时会校验令牌。 | «是» Пояснение: Symfony 表单默认启用 CSRF 保护,提交时会校验令牌。
Raw```json ⏎ {"answer": "是", "解释": "Symfony 表单默认启用 CSRF 保护,提交时会校验令牌。"} ⏎ ``` | верно | FormType добавляет скрытое поле _token и проверяет его при валидации; отключение — осознанное исключение (csrf: false). |
T22-L6 0.35 c | Symfony:安全与表单 | Symfony 的表单验证在服务器端执行,即使客户端(HTML5)检查已经通过。 | «是» Пояснение: 服务端验证是必要的安全和完整性保障,客户端验证仅提升用户体验。
Raw```json ⏎ {"answer": "是", "解释": "服务端验证是必要的安全和完整性保障,客户端验证仅提升用户体验。"} ⏎ ``` | верно | Клиентская валидация — только удобство; серверная обязательна и идёт по метаданным объекта формы. |
T22-L7 0.33 c | Symfony:安全与表单 | Symfony maker 的哪条命令会生成表单类(FormType)? | «make:form» Пояснение: 使用 Symfony MakerBundle 时,make:form 命令会生成表单类(FormType)。
Raw```json ⏎ {"answer": "make:form", "解释": "使用 Symfony MakerBundle 时,make:form 命令会生成表单类(FormType)。"} ⏎ ``` | верно | bin/console make:form (symfony/maker-bundle — в проекте). |
T22-L8 0.45 c | Symfony:安全与表单 | Symfony 以明文形式把用户密码存在会话中。 | «否» Пояснение: Symfony 通常不会把明文密码存到会话中,而是存储加密或哈希后的凭证,且具体实现取决于应用设计。
Raw{"answer": "否", "解释": "Symfony 通常不会把明文密码存到会话中,而是存储加密或哈希后的凭证,且具体实现取决于应用设计。"} | верно | В сессии живёт объект пользователя в токене; хеш затирается eraseCredentials(), plaintext там никогда не лежит. |
T23-L1 0.35 c | Symfony:配置与服务 | Symfony 的 bundle 配置放在 config/packages 中——每个 bundle 或主题一个文件。 | «是» Пояснение: Symfony 官方推荐将每个 bundle 的配置拆分到 config/packages 目录下的独立文件中,以实现更好的组织性和维护性。
Raw{"answer": "是", "解释": "Symfony 官方推荐将每个 bundle 的配置拆分到 config/packages 目录下的独立文件中,以实现更好的组织性和维护性。"} | верно | Стандартная структура (config/packages/*.yaml); перегрузка — config/packages/<env>. |
T23-L2 0.37 c | Symfony:配置与服务 | 包含开发默认值的 .env 文件会提交到仓库,而真正的机密放在不提交的 .env.local 中。 | «是» Пояснение: 这是推荐的最佳实践,.env 包含非敏感默认值以便团队协作,.env.local 存放敏感信息并忽略版本控制。
Raw{"answer": "是", "解释": "这是推荐的最佳实践,.env 包含非敏感默认值以便团队协作,.env.local 存放敏感信息并忽略版本控制。"} | верно | symfony/dotenv: .env — общий безопасный набор значений; локальные секреты — .env.local (gitignored) или secrets-хранилище. |
T23-L3 0.27 c | Symfony:配置与服务 | Symfony 的哪条命令会列出容器中注册的服务及其别名? | «debug:container» Пояснение: Symfony 使用 debug:container 命令来列出所有注册的服务及其别名。
Raw{"answer": "debug:container", "解释": "Symfony 使用 debug:container 命令来列出所有注册的服务及其别名。"} | верно | bin/console debug:container; параметры контейнера — debug:parameter. |
T23-L4 0.74 c | Symfony:配置与服务 | Symfony 容器允许在运行时修改参数:$container->setParameter() 可以在控制器中使用。 | «否» Пояснение: 现代 Symfony(3.3+ 及 4.0+)中,容器通常在编译时被冻结(freeze),运行时通过 $container->setParameter() 修改参数虽然语法上可能不报错,但并不推荐且行为可能不可靠,官方建议通过服务注入或动态获取而非直接修改容器参数。
Raw{"answer": "否", "解释": "现代 Symfony(3.3+ 及 4.0+)中,容器通常在编译时被冻结(freeze),运行时通过 $container->setParameter() 修改参数虽然语法上可能不报错,但并不推荐且行为可能不可靠,官方建议通过服务注入或动态获取而非直接修改容器参数。"} | верно | Контейнер компилируется и замораживается; runtime-значения — только через переменные окружения. |
T23-L5 0.33 c | Symfony:配置与服务 | 默认情况下,Symfony 的服务是公开的(public: true)——可以直接从容器中获取。 | «否» Пояснение: 默认情况下,Symfony 的服务是私有的(public: false),需要通过引用或其他服务访问。
Raw{"answer": "否", "解释": "默认情况下,Symfony 的服务是私有的(public: false),需要通过引用或其他服务访问。"} | верно | С Symfony 4.0 сервисы по умолчанию private: инжектятся через autowiring; $container->get() — только для публичных. |
T23-L6 0.37 c | Symfony:配置与服务 | 如果 config/packages 里没有配置文件,bundle 就无法工作——每个 bundle 都必须有配置。 | «否» Пояснение: 有些 Bundle(如 FrameworkBundle 或 TwigBundle)可以在没有显式配置的情况下工作,只要它们有合理的默认配置。
Raw{"answer": "否", "解释": "有些 Bundle(如 FrameworkBundle 或 TwigBundle)可以在没有显式配置的情况下工作,只要它们有合理的默认配置。"} | верно | У бандлов есть встроенные умолчания (Extension); конфиг нужен только для отклонений от них. |
T23-L7 0.31 c | Symfony:配置与服务 | 环境变量的值可以通过 %env(VAR)% 语法注入 services.yaml。 | «是» Пояснение: 在 Symfony 中,services.yaml 等配置文件支持使用 %env(VAR)% 语法来引用和注入环境变量。
Raw{"answer": "是", "解释": "在 Symfony 中,services.yaml 等配置文件支持使用 %env(VAR)% 语法来引用和注入环境变量。"} | верно | %env(...)% резолвится в рантайме env-процессорами; docs — Env Var Processors. |
T23-L8 0.26 c | Symfony:配置与服务 | Symfony 的哪个环境变量会开启调试模式(影响 profiler 和 Twig 调试)? | «app_debug» Пояснение: Symfony 中 APP_DEBUG 环境变量用于开启调试模式,影响 profiler 和 Twig 调试。
Raw{"answer": "APP_DEBUG", "解释": "Symfony 中 APP_DEBUG 环境变量用于开启调试模式,影响 profiler 和 Twig 调试。"} | верно | APP_DEBUG=1 (в .env dev-окружения); окружение выбирает APP_ENV — см. T13-L6. |
T16-L1 0.37 c | Symfony:Messenger | 在 Symfony Messenger 中,一条消息只能有一个处理者(handler)。 | «否» Пояснение: 一条消息可以被多个处理者(handler)处理,Symfony Messenger 支持消息被多个 handler 按顺序或并行处理。
Raw{"answer": "否", "解释": "一条消息可以被多个处理者(handler)处理,Symfony Messenger 支持消息被多个 handler 按顺序或并行处理。"} | верно | Messenger вызывает все хендлеры, подписанные на класс сообщения (docs — Multiple Handlers). |
T16-L2 0.35 c | Symfony:Messenger | Messenger 的 sync 传输会把消息放进队列交给 worker 处理,和 async 一样。 | «否» Пояснение: sync 传输直接同步执行消息处理,不会交给 worker 处理。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "sync 传输直接同步执行消息处理,不会交给 worker 处理。" ⏎ } ⏎ ``` | верно | Наоборот: sync обрабатывает немедленно в том же процессе, что и отправка; очередь — это async-транспорт. |
T16-L3 0.27 c | Symfony:Messenger | 哪条控制台命令会启动处理 Messenger 队列消息的 worker? | «bin/console messenger:consume» Пояснение: 这是 Symfony Messenger 组件用于启动 worker 以消费队列消息的标准命令。
Raw{"answer": "bin/console messenger:consume", "解释": "这是 Symfony Messenger 组件用于启动 worker 以消费队列消息的标准命令。"} | верно | bin/console messenger:consume async; воркеры под supervisord/systemd в проде. |
T16-L4 0.53 c | Symfony:Messenger | 失败消息的重试策略(retry_strategy)在 Messenger 传输层面配置。 | «是» Пояснение: 在 Symfony 的 Messenger 组件中,重试策略(retry_strategy)确实是配置在传输层(Transport)层面的,例如在配置文件或代码中设置传输的具体行为时指定。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "在 Symfony 的 Messenger 组件中,重试策略(retry_strategy)确实是配置在传输层(Transport)层面的,例如在配置文件或代码中设置传输的具体行为时指定。" ⏎ } ⏎ ``` | верно | retry_strategy на транспорте: max_retries, delay, multiplier; docs — Failed Messages & Retries. |
T16-L5 0.27 c | Symfony:Messenger | 默认情况下,Messenger 会把消息序列化为 JSON。 | «是» Пояснение: Symfony Messenger 默认使用 JSON 对消息进行序列化。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "Symfony Messenger 默认使用 JSON 对消息进行序列化。" ⏎ } ⏎ ``` | неверно верный: «否» | Дефолтный сериализатор — PhpSerializer (serialize()); JSON-сериализатор включается отдельно. |
T16-L6 0.33 c | Symfony:Messenger | Symfony Scheduler 按计划产生消息,并通过 Messenger 发送。 | «是» Пояснение: Symfony Scheduler 负责在指定时间触发任务,通常结合 Messenger 组件异步发送消息以执行实际逻辑。
Raw{"answer": "是", "解释": "Symfony Scheduler 负责在指定时间触发任务,通常结合 Messenger 组件异步发送消息以执行实际逻辑。"} | верно | Schedule → RecurringMessage → шина Messenger; docs — Scheduler. |
T16-L7 0.25 c | Symfony:Messenger | 哪个内置的 Messenger 传输通过 Doctrine 把消息存到数据库表中? | «doctrine» Пояснение: Doctrine 传输使用 Doctrine 将消息持久化存储到数据库中。
Raw{ ⏎ "answer": "doctrine", ⏎ "解释": "Doctrine 传输使用 Doctrine 将消息持久化存储到数据库中。" ⏎ } | верно | Транспорт doctrine (symfony/doctrine-messenger); таблица messenger_messages. В проекте стоит amqp-messenger + doctrine-messenger. |
T16-L8 0.37 c | Symfony:Messenger | Messenger 的管道可以用自定义 middleware 扩展,放在内置中间件之前或之后。 | «是» Пояснение: Symfony Messenger 允许在默认的中间件管道中插入自定义中间件,通过配置可以控制其相对于内置中间件的执行顺序。
Raw{"answer": "是", "解释": "Symfony Messenger 允许在默认的中间件管道中插入自定义中间件,通过配置可以控制其相对于内置中间件的执行顺序。"} | верно | messenger.bus.*.middleware в yaml; docs — Middleware. |
T28-L1 0.33 c | Symfony:版本 | Symfony 的主版本每两年发布一次,次版本每六个月一次(5 月和 11 月)。 | «是» Пояснение: Symfony 主版本每两年发布一次,次版本每六个月发布一次,分别在 5 月和 11 月。
Raw```json ⏎ {"answer": "是", "解释": "Symfony 主版本每两年发布一次,次版本每六个月发布一次,分别在 5 月和 11 月。"} ⏎ ``` | верно | Стандартный релизный цикл: 8.0 — ноябрь 2025, 8.1 — май 2026, 8.2 — ноябрь 2026. |
T28-L2 0.39 c | Symfony:版本 | Symfony 8 要求的最低 PHP 版本是多少? | «8.4» Пояснение: Symfony 7 要求 PHP 8.2+,而计划中的 Symfony 8 预计将提高最低 PHP 版本至 8.4。
Raw{"answer": "8.4", "解释": "Symfony 7 要求 PHP 8.2+,而计划中的 Symfony 8 预计将提高最低 PHP 版本至 8.4。"} | верно | Symfony 8.0 поднял требование до PHP >= 8.4.1 (в vendor проекта: "php": ">=8.4.1"). |
T28-L3 0.41 c | Symfony:版本 | Symfony 7.0 保留了对文档块注解(验证、路由)的支持。 | «否» Пояснение: Symfony 7.0 已移除对文档块注解(Docblocks)作为属性标签(如路由、验证)的支持,推荐使用 PHP 8 属性(Attributes)。
Raw{"answer": "否", "解释": "Symfony 7.0 已移除对文档块注解(Docblocks)作为属性标签(如路由、验证)的支持,推荐使用 PHP 8 属性(Attributes)。"} | верно | Наоборот: в 7.0 аннотации удалены — только PHP-атрибуты (#[Route], #[Assert\NotBlank]). |
T28-L4 0.39 c | Symfony:版本 | AssetMapper 无需 node 和 webpack 即可管理 CSS/JS——通过 importmap.php。 | «是» Пояснение: AssetMapper 是 Symfony 7 引入的轻量级前端构建工具,可通过 importmap.php 配置依赖,无需 node 和 webpack。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "AssetMapper 是 Symfony 7 引入的轻量级前端构建工具,可通过 importmap.php 配置依赖,无需 node 和 webpack。" ⏎ } ⏎ ``` | верно | symfony/asset-mapper (с 6.3, стандарт с 7.x); в проекте — importmap.php в корне и asset-mapper 8.1. |
T28-L5 0.33 c | Symfony:版本 | Symfony 6.4 是没有长期支持的普通版本。 | «否» Пояснение: Symfony 6.4 是长期支持(LTS)版本,其支持期延长了。
Raw{"answer": "否", "解释": "Symfony 6.4 是长期支持(LTS)版本,其支持期延长了。"} | верно | Наоборот: 6.4 — LTS (расширенная поддержка); LTS выходит вместе с очередным мажором (6.4 — вместе с 7.0). |
T28-L6 0.67 c | Symfony:版本 | 升级到新的 Symfony 主版本时,上一分支的弃用功能仍然可用——主版本不会移除它们。 | «是» Пояснение: 根据 Symfony 升级策略,功能通常在主版本 N 中标记为弃用(DEPRECATED),在主版本 N+1 中仍可用(通常伴随日志警告),直到主版本 N+2 才可能移除,因此升级到下一个主版本时上一分支的弃用功能通常仍然可用。
Raw{"answer": "是", "解释": "根据 Symfony 升级策略,功能通常在主版本 N 中标记为弃用(DEPRECATED),在主版本 N+1 中仍可用(通常伴随日志警告),直到主版本 N+2 才可能移除,因此升级到下一个主版本时上一分支的弃用功能通常仍然可用。"} | неверно верный: «否» | Наоборот: мажорный релиз удаляет всё устаревшее (7.0 убрал деприкейшены 6.x, 8.0 — 7.x). |
T28-L7 0.35 c | Symfony:版本 | Symfony 的每个主版本都附带列出变更的 UPGRADE 指南。 | «是» Пояснение: Symfony 的每个主版本都在 GitHub 仓库的 UPGRADE-x.x 文件中提供详细的升级指南。
Raw{"answer": "是", "解释": "Symfony 的每个主版本都在 GitHub 仓库的 UPGRADE-x.x 文件中提供详细的升级指南。"} | верно | UPGRADE-7.0.md, UPGRADE-8.0.md в репозитории symfony/symfony. |
T28-L8 0.37 c | Symfony:版本 | Symfony 的哪个组件在没有 node/webpack 的情况下管理资源和 importmap? | «assetmapper» Пояснение: Symfony 7.1 引入的 AssetMapper 组件可在没有 Node.js 的情况下管理静态资源并生成 import map。
Raw{"answer": "AssetMapper", "解释": "Symfony 7.1 引入的 AssetMapper 组件可在没有 Node.js 的情况下管理静态资源并生成 import map。"} | верно | symfony/asset-mapper 8.1 — в проекте. |
T29-L1 0.33 c | Symfony:8.2 与未来 | 截至 2026-11-07,Symfony 8.2 已经发布。 | «是» Пояснение: 根据提供的信息,截至 2026-11-07,Symfony 8.2 已经发布。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "根据提供的信息,截至 2026-11-07,Symfony 8.2 已经发布。" ⏎ } ⏎ ``` | неверно верный: «否» | Наоборот: 8.2 ещё не выпущена — релиз в конце ноября 2026; последняя стабильная — 8.1. |
T29-L2 8.68 c | Symfony:8.2 与未来 | 截至 2026-11-07,Symfony 8.2 计划于 2026 年 11 月发布,遵循通常的六个月周期。 | «否» Пояснение: , every 2 years.\nSo 8.0 would be Nov 2026.\nThen 8.1 would be May 2027.\nThen 8.2 would be Nov 2027.\nThe statement says "Symfony 8.2 ... planned for November 2026". This contradicts the standard cycle where 8.2 would be a year after 8.0. Even if the cycle is strictly 6 months per minor version, 8.0 (Nov 2026) -> 8.1 (May 2027) -> 8.2 (Nov 2027). So 8.2 in Nov 2026 is incorrect. It would be 8.0 in Nov 2026."
Raw{"answer": "否", "解释": "Symfony 通常每年发布两个主要版本(5月和11月),但版本号(如 8.2)具体是否对应 2026 年 11 月取决于 Symfony 8.0 的发布时间和小版本迭代计划,且“计划于”这种确切日期的陈述在长期预测中往往不绝对准确,但更关键的是 Symfony 8 尚未发布(截至 2026 年),其具体版本命名和日期需官方确认,通常 8.0 会在 2025 或 2026 初发布,8.2 可能在 2026 年底或 2027 初,因此该陈述存在不确定性,但按常规节奏 8.2 不太可能正好在 2026 年 11 月,更可能是 2026 年 5 月发布 8.1,11 月发布 8.2,所以这句话逻辑上是可能的,但“计划于 2026 年 11 月发布”是具体计划,通常 Symfony 版本发布日期是固定的(5月和11月),如果 8.0 在 2025 年 11 月发布,那么 8.1 在 2026 年 5 月,8.2 在 2026 年 11 月,这样是合理的。但是,问题问的是“对还是错”,通常这类题目考察的是对 Symfony 发布节奏的了解。Symfony 8.0 预计在 2025 年 11 月发布(继 7.3 之后),那么 8.1 在 2026 年 5 月,8.2 在 2026 年 11 月。这个推论是合理的。然而,严格来说,如果没有官方确切公告,说“计划于”可能被视为正确,因为这是基于现有节奏的推断。但在测试题中,往往有一个陷阱。让我们再仔细看。Symfony 7.3 发布于 2024 年 11 月(假设),那么 7.4 在 2025 年 5 月?不对,Symfony 通常每年发布两个 LTS 和非 LTS。实际上,Symfony 5.0 发布于 2021 年 11 月,5.1 在 2021 年 5 月(不对,是 5.0 在 2021.11,5.1 在 2021.5?不,5.0 是 2021.11,5.1 是 2021.5 是错的,5.1 是 2021 年 5 月?查一下:Symfony 5.0 (2021-11), 5.1 (2021-05? No, 5.1 was 2021-05? Actually 5.0 was Nov 2021, 5.1 was May 2021 is backwards. Let's recall: 4.4 was Aug 2019, 5.0 Nov 2019? No. \nLet's check standard Symfony release dates:\nSymfony 4.0: Nov 2017\nSymfony 4.1: May 2018\nSymfony 4.2: Nov 2018\nSymfony 4.3: May 2019\nSymfony 4.4: Nov 2019 (LTS)\nSymfony 5.0: Nov 2020\nSymfony 5.1: May 2021\nSymfony 5.2: Nov 2021\nSymfony 5.3: May 2022\nSymfony 5.4: Nov 2021 (LTS)\nSymfony 6.0: Nov 2022\nSymfony 6.1: May 2023\nSymfony 6.2: Nov 2023\nSymfony 6.3: May 2024\nSymfony 6.4: Nov 2023 (LTS)\nSymfony 7.0: Nov 2024\nSymfony 7.1: May 2025\nSymfony 7.2: Nov 2025\nSymfony 7.3: May 2026\nSymfony 8.0: Nov 2026?\nWait, if 7.0 is Nov 2024, then 7.1 is May 2025, 7.2 is Nov 2025, 7.3 is May 2026, 7.4 is Nov 2026? Or does 8.0 start at Nov 2026? Usually, major versions come out in November. So 8.0 would be Nov 2026. Then 8.1 would be May 2027. So 8.2 would be Nov 2027. Therefore, saying 8.2 is planned for Nov 2026 is likely **Wrong**.\n\nLet's double check the pattern:\nMajor versions: 5.0 (Nov 2020), 6.0 (Nov 2022), 7.0 (Nov 2024). This implies major versions are released every 2 years in November? Or is it that 5.0 was 2020, 6.0 was 2022, 7.0 is 2024. Yes, every 2 years.\nSo 8.0 would be Nov 2026.\nThen 8.1 would be May 2027.\nThen 8.2 would be Nov 2027.\nThe statement says "Symfony 8.2 ... planned for November 2026". This contradicts the standard cycle where 8.2 would be a year after 8.0. Even if the cycle is strictly 6 months per minor version, 8.0 (Nov 2026) -> 8.1 (May 2027) -> 8.2 (Nov 2027). So 8.2 in Nov 2026 is incorrect. It would be 8.0 in Nov 2026." | неверно верный: «是» парсинг: текст (фолбэк) | Политика релизов: 8.1 — май 2026, 8.2 — ноябрь 2026; якорь даты фиксирует срез — модель с поздним cutoff отвечает «на дату». |
T29-L3 0.55 c | Symfony:8.2 与未来 | 在 8.1 之后(截至 2026-11-07)会发布哪个 Symfony 版本? | «7.2» Пояснение: Symfony 7.1 发布后,按照每半年一个主版本的发布节奏,8.1(假设指 7.1)之后的下一个稳定版本是 7.2。
Raw{"answer": "7.2", "解释": "Symfony 7.1 发布后,按照每半年一个主版本的发布节奏,8.1(假设指 7.1)之后的下一个稳定版本是 7.2。"} | неверно верный: «8.2» | 8.2 — следующий минорный релиз (ноябрь 2026); после его выхода проект переходит с 8.1.* на 8.2.*. |
T29-L4 0.7 c | Symfony:8.2 与未来 | Symfony 8.2 是一个主版本,需要为新的 API 重写应用程序。 | «否» Пояснение: Symfony 使用主要版本(major version)来引入可能不向后兼容的重大变更,而 8.2 是一个次版本(minor version),它通常包含新功能或增强,不会破坏已有应用程序的兼容性。
Raw```json ⏎ {"answer": "否", "解释": "Symfony 使用主要版本(major version)来引入可能不向后兼容的重大变更,而 8.2 是一个次版本(minor version),它通常包含新功能或增强,不会破坏已有应用程序的兼容性。"} ⏎ ``` | верно | Наоборот: 8.2 — минорный релиз; новые возможности без поломки обратной совместимости. Мажор — 9.0. |
T29-L5 0.71 c | Symfony:8.2 与未来 | 在主分支内更新(8.1 → 8.2)不应需要修改代码——保持向后兼容。 | «否» Пояснение: PHP 主版本号(Minor Version)升级时,允许引入新特性、废弃功能甚至移除功能,不保证完全向后兼容(BC Breaks),只有补丁版本(Patch Version)升级才严格保持向后兼容。
Raw{"answer": "否", "解释": "PHP 主版本号(Minor Version)升级时,允许引入新特性、废弃功能甚至移除功能,不保证完全向后兼容(BC Breaks),只有补丁版本(Patch Version)升级才严格保持向后兼容。"} | неверно верный: «是» | Политика Symfony: минорные релизы обратно совместимы; BC-break допустим только в мажорных. |
T29-L6 0.41 c | Symfony:8.2 与未来 | 在 Symfony 9.0 之前,8.x 分支的最后一个次版本是什么? | «8.4» Пояснение: Symfony 的版本发布遵循主版本.次版本的格式,8.x 分支的最后一个次版本是 8.4。
Raw{"answer": "8.4", "解释": "Symfony 的版本发布遵循主版本.次版本的格式,8.x 分支的最后一个次版本是 8.4。"} | верно | По циклу: 8.2 (ноя 2026), 8.3 (май 2027), 8.4 (ноя 2027, вместе с 9.0) — как 6.4 выходила вместе с 7.0. |
T29-L7 2.3 c | Symfony:8.2 与未来 | Symfony 8.2 将要求 PHP 8.5——必须随之升级 PHP。 | «否» Пояснение: Symfony 8.0 要求 PHP 8.4,且 Symfony 采用“一年一个主版本”的发布节奏,Symfony 8.2 预计对应 PHP 8.5 的说法并不准确,通常 Symfony 8.x 系列支持 PHP 8.4+,具体小版本对 PHP 版本的要求需参照官方文档,目前官方并未宣布 8.2 强制要求 8.5(通常大版本升级才强制 PHP 大版本更新);更重要的是,截至 2024/2025 年,Symfony 8.0 要求 PHP 8.4,而 Symfony 8.1/8.2 通常继续支持该 PHP 版本或更高,但“必须”随之升级到 8.5 并非绝对规则,且题目中“8.2 要求 8.5”缺乏官方确凿依据,常规认知中 Symfony 主版本与 PHP 主版本大致对应,但小版本间 PHP 要求不一定递增到 8.5。更关键的是,Symfony 8 系列(包括 8.0, 8.1, 8.2)的最低 PHP 版本要求通常是 8.4,而不是 8.5。
Raw{"answer": "否", "解释": "Symfony 8.0 要求 PHP 8.4,且 Symfony 采用“一年一个主版本”的发布节奏,Symfony 8.2 预计对应 PHP 8.5 的说法并不准确,通常 Symfony 8.x 系列支持 PHP 8.4+,具体小版本对 PHP 版本的要求需参照官方文档,目前官方并未宣布 8.2 强制要求 8.5(通常大版本升级才强制 PHP 大版本更新);更重要的是,截至 2024/2025 年,Symfony 8.0 要求 PHP 8.4,而 Symfony 8.1/8.2 通常继续支持该 PHP 版本或更高,但“必须”随之升级到 8.5 并非绝对规则,且题目中“8.2 要求 8.5”缺乏官方确凿依据,常规认知中 Symfony 主版本与 PHP 主版本大致对应,但小版本间 PHP 要求不一定递增到 8.5。更关键的是,Symfony 8 系列(包括 8.0, 8.1, 8.2)的最低 PHP 版本要求通常是 8.4,而不是 8.5。"} | верно | Наоборот: минорные релизы не поднимают требования PHP; для всей ветки 8.x остаётся PHP >= 8.4. |
T29-L8 0.5 c | Symfony:8.2 与未来 | 在 8.x 分支中添加的弃用功能,最早也要到 Symfony 9.0 才会移除。 | «是» Пояснение: 根据 Symfony 的废弃流程,在 8.x 分支(即 7.x 之后)引入的弃用功能,通常至少保留到下一个主版本(9.0)才会被移除。
Raw{"answer": "是", "解释": "根据 Symfony 的废弃流程,在 8.x 分支(即 7.x 之后)引入的弃用功能,通常至少保留到下一个主版本(9.0)才会被移除。"} | верно | Политика: деприкейшены живут до следующего мажора; 9.0 — ноябрь 2027. |
T21-L1 0.43 c | Twig | 在 Twig 中,{{ }} 里面可以直接调用任意的 PHP 代码。 | «否» Пояснение: Twig 中 {{ }} 主要用于表达式求值,不能直接调用任意 PHP 代码,而应通过函数、过滤器或自定义标签来处理。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "Twig 中 {{ }} 主要用于表达式求值,不能直接调用任意 PHP 代码,而应通过函数、过滤器或自定义标签来处理。" ⏎ } ⏎ ``` | верно | Twig — DSL: только разрешённые окружением функции/фильтры; произвольный PHP не исполняется. |
T21-L2 0.27 c | Twig | 默认情况下,Twig 会自动转义输出的变量。 | «是» Пояснение: 在 Twig 中,默认情况下会自动转义输出的变量,以防止 XSS 等攻击。
Raw```json ⏎ {"answer": "是", "解释": "在 Twig 中,默认情况下会自动转义输出的变量,以防止 XSS 等攻击。"} ⏎ ``` | верно | Autoescape включён по умолчанию; {{ '<b>' }} → <b>. Проверено на Twig 3.30. |
T21-L3 0.33 c | Twig | Twig 的 |e 过滤器会对字符串进行转义,以便在 HTML 上下文中安全输出。 | «是» Пояснение: |e 过滤器在 Twig 中用于 HTML 转义,防止 XSS 攻击。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "|e 过滤器在 Twig 中用于 HTML 转义,防止 XSS 攻击。" ⏎ } ⏎ ``` | верно | |e ('html') по умолчанию; есть контексты js/url/css. От SQL-инъекций он не защищает — это задача подготовленных запросов Doctrine. |
T21-L4 0.27 c | Twig | twig/intl-extra 中哪个过滤器按本地化设置格式化数字? | «number_format» Пояснение: twig/intl-extra 中的 number_format 过滤器使用 intl 扩展按本地化设置格式化数字。
Raw{"answer": "number_format", "解释": "twig/intl-extra 中的 number_format 过滤器使用 intl 扩展按本地化设置格式化数字。"} | неверно верный: «format_number» | |format_number(locale=...) из IntlExtension (twig/intl-extra есть в проекте). Проверено на Twig 3.30: 12345.6 → 12 345,6 (ru). |
T21-L5 0.35 c | Twig | |raw 过滤器会对值关闭自动转义。 | «是» Пояснение: raw 过滤器在模板引擎(如 Twig 或 Laravel Blade)中用于禁用自动转义,直接输出原始值。
Raw{"answer": "是", "解释": "raw 过滤器在模板引擎(如 Twig 或 Laravel Blade)中用于禁用自动转义,直接输出原始值。"} | верно | {{ x|raw }} выводит HTML как есть; опасно с пользовательскими данными. Проверено на Twig 3.30. |
T21-L6 0.48 c | Twig | 在 Twig 中,{{ }} 输出表达式的值,而 {% %} 执行标签——条件、循环、set。 | «是» Пояснение: 在 Twig 模板引擎中,双花括号 {{ }} 用于输出表达式的值,而花括号 {% %} 用于执行控制结构标签(如 if, for, set 等)。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "在 Twig 模板引擎中,双花括号 {{ }} 用于输出表达式的值,而花括号 {% %} 用于执行控制结构标签(如 if, for, set 等)。" ⏎ } ⏎ ``` | верно | Два блока синтаксиса Twig: вывод (echo) против логики. |
T21-L7 0.3 c | Twig | Twig 模板中不能声明变量——值只能由控制器传入。 | «否» Пояснение: Twig 模板内部可以通过 set 语句声明变量。
Raw```json ⏎ {"answer": "否", "解释": "Twig 模板内部可以通过 set 语句声明变量。"} ⏎ ``` | верно | {% set y = ... %} объявляет переменную в шаблоне. Проверено на Twig 3.30. |
T21-L8 0.25 c | Twig | Twig 的哪个函数会输出变量的调试结构(数组、对象)? | «dump» Пояснение: Twig 使用 dump 函数来输出变量的调试结构,如数组、对象等。
Raw{"answer": "dump", "解释": "Twig 使用 dump 函数来输出变量的调试结构,如数组、对象等。"} | верно | {{ dump(x) }} (DebugExtension; в Symfony доступна в dev-окружении). |
T24-L1 0.35 c | Bootstrap | Bootstrap 是一套现成 UI 组件的 CSS/JS 库,而不是 SPA 框架。 | «是» Пояснение: Bootstrap 主要提供 HTML、CSS 和少量 JavaScript 组件,用于构建响应式前端界面,而非单页应用框架。
Raw{"answer": "是", "解释": "Bootstrap 主要提供 HTML、CSS 和少量 JavaScript 组件,用于构建响应式前端界面,而非单页应用框架。"} | верно | Компоненты и утилиты поверх вашего HTML; SPA-фреймворки (React/Vue) — другой класс инструментов. В проекте vendored 5.3.3. |
T24-L2 0.25 c | Bootstrap | Bootstrap 的哪个类提供了按断点固定最大宽度的响应式容器? | «container» Пояснение: Bootstrap 中 .container 类根据断点提供最大宽度的响应式固定容器。
Raw{"answer": "container", "解释": "Bootstrap 中 .container 类根据断点提供最大宽度的响应式固定容器。"} | верно | .container (фиксированная макс-ширина по брейкпоинтам) vs .container-fluid (на всю ширину). |
T24-L3 0.31 c | Bootstrap | Bootstrap 的栅格基于 CSS float,把一行分成 16 列。 | «否» Пояснение: Bootstrap 4 及后续版本基于 Flexbox,且标准栅格系统为 12 列。
Raw{"answer": "否", "解释": "Bootstrap 4 及后续版本基于 Flexbox,且标准栅格系统为 12 列。"} | верно | Наоборот: flexbox (с Bootstrap 4) и 12 колонок; float-сетка — это Bootstrap 3. |
T24-L4 0.26 c | Bootstrap | Bootstrap 的命名断点(类名中的中缀)是 sm、md、lg、xl、xxl——共五个。 | «是» Пояснение: Bootstrap 5 的命名断点确实为 sm、md、lg、xl、xxl 这五个。
Raw{"answer": "是", "解释": "Bootstrap 5 的命名断点确实为 sm、md、lg、xl、xxl 这五个。"} | верно | Тиров всего шесть: xs (без инфикса) + пять именованных (576/768/992/1200/1400 px). |
T24-L5 0.38 c | Bootstrap | 像 .mt-3 或 .px-2 这样的工具类使用间距刻度:数字是 $spacer 的倍数。 | «是» Пояснение: 在 Bootstrap 中,工具类如 .mt-3 或 .px-2 的间距值确实是 $spacer 变量的倍数,例如 mt-3 对应 3 * $spacer。
Raw{"answer": "是", "解释": "在 Bootstrap 中,工具类如 .mt-3 或 .px-2 的间距值确实是 $spacer 变量的倍数,例如 mt-3 对应 3 * $spacer。"} | неверно верный: «否» | Spacing utilities; $spacer = 1rem. |
T24-L6 0.39 c | Bootstrap | Bootstrap 5 的哪个 data 属性可以在元素上启用交互组件(例如 dropdown)? | «data-bs-toggle» Пояснение: Bootstrap 5 使用 data-bs-toggle 属性来激活如 dropdown、modal 等交互组件的行为。
Raw```json ⏎ { ⏎ "answer": "data-bs-toggle", ⏎ "解释": "Bootstrap 5 使用 data-bs-toggle 属性来激活如 dropdown、modal 等交互组件的行为。" ⏎ } ⏎ ``` | верно | data-bs-toggle="dropdown" и т.п.; в Bootstrap 4 атрибут назывался data-toggle. |
T24-L7 0.31 c | Bootstrap | Bootstrap 5 的组件不依赖 jQuery——使用原生 JS。 | «是» Пояснение: Bootstrap 5 移除了对 jQuery 的依赖,转而使用原生 JavaScript 或 Popper.js。
Raw{"answer": "是", "解释": "Bootstrap 5 移除了对 jQuery 的依赖,转而使用原生 JavaScript 或 Popper.js。"} | верно | jQuery удалён в Bootstrap 5.0: data-bs-* атрибуты и JS API. В проекте vendored 5.3.3. |
T24-L8 0.41 c | Bootstrap | Bootstrap 的深色模式是通过在根元素上添加 .dark 类开启的。 | «是» Пояснение: Bootstrap 5 确实通过给 <html> 或根元素添加 .dark 类来启用深色模式,触发 prefers-color-scheme: dark 的样式。
Raw{"answer": "是", "解释": "Bootstrap 5 确实通过给 <html> 或根元素添加 .dark 类来启用深色模式,触发 prefers-color-scheme: dark 的样式。"} | неверно верный: «否» | Наоборот: тема включается атрибутом data-bs-theme="dark" (Color modes, с 5.3); класса .dark не существует. В проекте 5.3.3. |
T14-L1 0.39 c | Doctrine | Doctrine ORM 会在运行时首次使用实体时自动在数据库中创建表。 | «否» Пояснение: Doctrine ORM 默认不会在运行时自动创建表,通常需要通过迁移(如 Doctrine Migrations)或命令工具手动同步数据库架构。
Raw{"answer": "否", "解释": "Doctrine ORM 默认不会在运行时自动创建表,通常需要通过迁移(如 Doctrine Migrations)或命令工具手动同步数据库架构。"} | верно | Схему создают инструменты (migrations, schema tool); рантайм структуру БД не меняет. |
T14-L2 0.28 c | Doctrine | EntityManager 的哪个方法把新对象标记为受管理(managed),而 SQL 延迟到 flush() 才执行? | «persist()» Пояснение: persist() 方法将对象置于受管理状态,但不立即执行 SQL,直到调用 flush()。
Raw{"answer": "persist()", "解释": "persist() 方法将对象置于受管理状态,但不立即执行 SQL,直到调用 flush()。"} | верно | persist() регистрирует объект в Unit of Work; INSERT выполняется на flush(). |
T14-L3 0.47 c | Doctrine | 在 Doctrine ORM 3 中,EntityManager::merge() 方法存在,并把传入的对象变成受管理的。 | «是» Пояснение: 在 Doctrine ORM 3 中,`EntityManager::merge()` 方法用于将游离(detached)或托管(managed)对象合并到当前单元管理器中,使其变成受管理的状态。
Raw{"answer": "是", "解释": "在 Doctrine ORM 3 中,`EntityManager::merge()` 方法用于将游离(detached)或托管(managed)对象合并到当前单元管理器中,使其变成受管理的状态。"} | неверно верный: «否» | В ORM 3 merge() удалён (в vendor проекта 3.7.6 метода нет); в Doctrine 2.x merge() возвращал управляемую копию. Версия зафиксирована — ORM 3. |
T14-L4 0.37 c | Doctrine | DQL 查询以实体及其字段为单位编写,而不是表和列。 | «是» Пояснение: DQL(Doctrine Query Language)确实是以实体及其字段为单位的查询语言,而不是直接操作数据库表和列。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "DQL(Doctrine Query Language)确实是以实体及其字段为单位的查询语言,而不是直接操作数据库表和列。" ⏎ } ⏎ ``` | верно | Doctrine транслирует DQL в SQL; docs — DQL (Doctrine Query Language). |
T14-L5 0.22 c | Doctrine | 如果不存在 id 为 999 的记录,$repository->find(999) 返回什么? | «null» Пояснение: Doctrine 的 find() 方法在找不到记录时返回 null。
Raw{"answer": "null", "解释": "Doctrine 的 find() 方法在找不到记录时返回 null。"} | верно | find() возвращает null, если объект не найден (docs Repository methods). |
T14-L6 0.51 c | Doctrine | Symfony 的 DoctrineBundle 会在每个请求结束时自动调用 flush()。 | «否» Пояснение: DoctrineBundle 默认配置下不会自动 flush,通常需要手动调用或使用事务管理(如 EventSubscriber/Listener 或 Controller 中明确调用)。
Raw{ ⏎ "answer": "否", ⏎ "解释": "DoctrineBundle 默认配置下不会自动 flush,通常需要手动调用或使用事务管理(如 EventSubscriber/Listener 或 Controller 中明确调用)。" ⏎ } | верно | Авто-flush нет — flush() зовёт разработчик; незакрытая транзакция в конце запроса откатывается. |
T14-L7 0.5 c | Doctrine | 对于受管理的实体,只需修改属性即可:flush() 会在没有显式 persist() 的情况下提交更改——Unit of Work 会追踪变更。 | «是» Пояснение: 在 Doctrine 中,受管理的实体(managed entities)的变更可以通过 Unit of Work 的变更追踪机制自动检测,因此在调用 flush() 时会提交更改,无需显式调用 persist()。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "在 Doctrine 中,受管理的实体(managed entities)的变更可以通过 Unit of Work 的变更追踪机制自动检测,因此在调用 flush() 时会提交更改,无需显式调用 persist()。" ⏎ } ⏎ ``` | верно | Dirty checking сравнивает снимки свойств; persist нужен только новым/отсоединённым объектам. |
T14-L8 0.41 c | Doctrine | remove() 会立即执行 SQL DELETE,不会等到 flush()。 | «否» Пояснение: Doctrine ORM 的 remove() 只是将实体标记为待删除,实际执行 DELETE 语句需等待 flush() 调用。
Raw{"answer": "否", "解释": "Doctrine ORM 的 remove() 只是将实体标记为待删除,实际执行 DELETE 语句需等待 flush() 调用。"} | верно | remove() планирует удаление в Unit of Work; DELETE выполняется на flush() (docs — Deleting Objects). |
T15-L1 0.37 c | PostgreSQL | PostgreSQL 使用 MVCC,因此读会阻塞写,写也会阻塞读。 | «否» Пояснение: PostgreSQL 的 MVCC 机制允许读写并发,读不阻塞写,写也不阻塞读(同事务内除外)。
Raw{"answer": "否", "解释": "PostgreSQL 的 MVCC 机制允许读写并发,读不阻塞写,写也不阻塞读(同事务内除外)。"} | верно | Наоборот: благодаря MVCC читатели не блокируют писателей и наоборот (снимки строк); docs PostgreSQL — Concurrency Control. |
T15-L2 0.27 c | PostgreSQL | 哪条 SQL 命令会显示查询的执行计划,而不实际执行查询? | «explain» Пояснение: 在 MySQL 中,EXPLAIN 关键字用于显示查询的执行计划而不实际执行它。
Raw{"answer": "EXPLAIN", "解释": "在 MySQL 中,EXPLAIN 关键字用于显示查询的执行计划而不实际执行它。"} | верно | EXPLAIN без ANALYZE только строит план; проверено на PostgreSQL 17.7. |
T15-L3 1.02 c | PostgreSQL | SERIAL 和 GENERATED ... AS IDENTITY 只是同一机制的两个名称。 | «是» Пояснение: 在 PHP(特别是结合某些数据库如 MySQL 8.0 及以上版本或 PostgreSQL)中,SERIAL 和 GENERATED ... AS IDENTITY 都可以用于定义自增列。SERIAL 是早期 PostgreSQL 中的自增列的简写形式,而 GENERATED ... AS IDENTITY 是 SQL 标准中定义标识列的方式。尽管它们在实现上可能有细微差别,但从功能上看,它们都可以实现类似的自增效果,因此可以说它们是同一机制的两个不同表述方式。
Raw```json ⏎ {"answer": "是", "解释": "在 PHP(特别是结合某些数据库如 MySQL 8.0 及以上版本或 PostgreSQL)中,SERIAL 和 GENERATED ... AS IDENTITY 都可以用于定义自增列。SERIAL 是早期 PostgreSQL 中的自增列的简写形式,而 GENERATED ... AS IDENTITY 是 SQL 标准中定义标识列的方式。尽管它们在实现上可能有细微差别,但从功能上看,它们都可以实现类似的自增效果,因此可以说它们是同一机制的两个不同表述方式。"} ⏎ ``` | неверно верный: «否» | SERIAL — нестандартный макрос (sequence + DEFAULT), IDENTITY — SQL-стандарт; различаются владением и правами. Оба есть в PG 17 (проверено). |
T15-L4 0.34 c | PostgreSQL | 默认情况下,PostgreSQL 的 UNIQUE 约束在列中只允许一行 NULL。 | «否» Пояснение: PostgreSQL 默认允许 UNIQUE 约束中存在多行 NULL 值,因为 SQL 标准中 NULL 不等于 NULL。
Raw{"answer": "否", "解释": "PostgreSQL 默认允许 UNIQUE 约束中存在多行 NULL 值,因为 SQL 标准中 NULL 不等于 NULL。"} | верно | Наоборот: NULLS DISTINCT по умолчанию — несколько NULL допустимы; NULLS NOT DISTINCT — опция с PG 15. Проверено на PG 17.7. |
T15-L5 0.33 c | PostgreSQL | PostgreSQL 的哪个聚合函数用分隔符拼接字符串? | «string_agg» Пояснение: string_agg 是 PostgreSQL 中用于通过指定分隔符将多个字符串值拼接成一个字符串的内置聚合函数。
Raw{"answer": "string_agg", "解释": "string_agg 是 PostgreSQL 中用于通过指定分隔符将多个字符串值拼接成一个字符串的内置聚合函数。"} | верно | string_agg(значение, разделитель); проверено на PostgreSQL 17.7. |
T15-L6 0.41 c | PostgreSQL | 普通 VACUUM 会把死元组占用的空间归还给操作系统。 | «否» Пояснение: 普通 VACUUM 只标记空间以便复用,不归还给操作系统;VACUUM FULL 才真正归还空间。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "普通 VACUUM 只标记空间以便复用,不归还给操作系统;VACUUM FULL 才真正归还空间。" ⏎ } ⏎ ``` | верно | VACUUM помечает место для переиспользования внутри таблицы; ОС его возвращает только VACUUM FULL (с эксклюзивной блокировкой). |
T15-L7 0.38 c | PostgreSQL | 在窗口函数的定义中,哪个关键字把行分成若干组,函数按组计算? | «over» Пояснение: OVER 关键字用于定义窗口函数的作用范围,通过 PARTITION BY 或 ORDER BY 等子句将行分组并进行计算。
Raw{"answer": "OVER", "解释": "OVER 关键字用于定义窗口函数的作用范围,通过 PARTITION BY 或 ORDER BY 等子句将行分组并进行计算。"} | неверно верный: «partition by» | OVER (PARTITION BY ...); проверено на PostgreSQL 17.7. |
T15-L8 0.27 c | PostgreSQL | READ COMMITTED 隔离级别能防止不可重复读(non-repeatable read)。 | «否» Пояснение: READ COMMITTED 隔离级别只能防止脏读,不能防止不可重复读和幻读。
Raw{"answer": "否", "解释": "READ COMMITTED 隔离级别只能防止脏读,不能防止不可重复读和幻读。"} | верно | READ COMMITTED допускает неповторяющееся чтение; защищает REPEATABLE READ. Проверено: SHOW transaction_isolation → read committed. |
T17-L1 0.51 c | PostgreSQL:事务与索引 | 默认情况下,PostgreSQL 会把每条单独的 SQL 语句包在自己的隐式事务中(autocommit)。 | «是» Пояснение: 默认情况下,PostgreSQL 采用自动提交(autocommit)模式,每条单独的 SQL 语句会立即在其自身的隐式事务中提交,除非显式开始一个事务(例如使用 BEGIN)。
Raw```json ⏎ { ⏎ "answer": "是", ⏎ "解释": "默认情况下,PostgreSQL 采用自动提交(autocommit)模式,每条单独的 SQL 语句会立即在其自身的隐式事务中提交,除非显式开始一个事务(例如使用 BEGIN)。" ⏎ } ⏎ ``` | верно | Без BEGIN каждый оператор коммитится сам; docs PostgreSQL — Transactions. Проверено на PG 17. |
T17-L2 0.31 c | PostgreSQL:事务与索引 | 哪条 SQL 命令结束事务并保存其中的所有更改? | «commit» Пояснение: COMMIT 语句用于提交当前事务,将更改永久保存到数据库中。
Raw{"answer": "COMMIT", "解释": "COMMIT 语句用于提交当前事务,将更改永久保存到数据库中。"} | верно | COMMIT (END — синоним). Проверено на PG 17. |
T17-L3 0.25 c | PostgreSQL:事务与索引 | 索引加速的不只是 SELECT:按索引列查找的 UPDATE 和 DELETE 同样受益。 | «是» Пояснение: 索引通过快速定位数据行,同样加速了 UPDATE 和 DELETE 操作。
Raw{"answer": "是", "解释": "索引通过快速定位数据行,同样加速了 UPDATE 和 DELETE 操作。"} | верно | Поиск строк для изменения идёт по индексу; docs PostgreSQL — Indexes. |
T17-L4 0.37 c | PostgreSQL:事务与索引 | 要回滚事务中的部分语句,PostgreSQL 使用 SAVEPOINT。 | «是» Пояснение: PostgreSQL 支持使用 SAVEPOINT 创建保存点,从而允许回滚到特定的保存点,而不会撤销该点之前的所有事务操作。
Raw{"answer": "是", "解释": "PostgreSQL 支持使用 SAVEPOINT 创建保存点,从而允许回滚到特定的保存点,而不会撤销该点之前的所有事务操作。"} | верно | SAVEPOINT name; ROLLBACK TO name — частичный откат без отмены всей транзакции. Проверено на PG 17. |
T17-L5 0.34 c | PostgreSQL:事务与索引 | EXPLAIN ANALYZE 显示查询计划,而不实际执行查询。 | «否» Пояснение: EXPLAIN ANALYZE 会实际执行查询以获取运行时间和行数,而 EXPLAIN 才只显示计划不执行。
Raw{"answer": "否", "解释": "EXPLAIN ANALYZE 会实际执行查询以获取运行时间和行数,而 EXPLAIN 才只显示计划不执行。"} | верно | Наоборот: ANALYZE реально выполняет запрос (с побочными эффектами!) и показывает фактические времена узлов; план без выполнения — plain EXPLAIN. |
T17-L6 0.31 c | PostgreSQL:事务与索引 | 哪个 PostgreSQL 扩展为向量(embedding)搜索添加了向量类型和索引? | «pgvector» Пояснение: pgvector 是 PostgreSQL 的扩展,它提供了向量类型和索引,用于高效的向量相似度搜索。
Raw```json ⏎ {"answer": "pgvector", "解释": "pgvector 是 PostgreSQL 的扩展,它提供了向量类型和索引,用于高效的向量相似度搜索。"} ⏎ ``` | верно | CREATE EXTENSION vector (проект pgvector; в проекте образ pgvector/pgvector:pg17). |
T17-L7 0.33 c | PostgreSQL:事务与索引 | 部分索引(CREATE INDEX ... WHERE ...)只为满足条件的行构建。 | «是» Пояснение: 部分索引(Partial Index)确实只为满足 WHERE 子句条件的行构建索引,从而节省空间并提高查询效率。
Raw{"answer": "是", "解释": "部分索引(Partial Index)确实只为满足 WHERE 子句条件的行构建索引,从而节省空间并提高查询效率。"} | верно | docs PostgreSQL — Partial Indexes; типичный кейс — индекс по «активным» записям. |
T17-L8 0.43 c | PostgreSQL:事务与索引 | PostgreSQL 的 SERIALIZABLE 隔离级别是通过锁定事务读取的行来实现的。 | «否» Пояснение: PostgreSQL 的 SERIALIZABLE 隔离级别使用 MVCC 机制和串行化检查实现,而不是仅依靠锁定读取的行。
Raw```json ⏎ {"answer": "否", "解释": "PostgreSQL 的 SERIALIZABLE 隔离级别使用 MVCC 机制和串行化检查实现,而不是仅依靠锁定读取的行。"} ⏎ ``` | верно | SSI (Serializable Snapshot Isolation): предикатные блокировки на снимках, не блокировки прочитанных строк; docs PostgreSQL. |
T19-L1 0.31 c | HTTP 与 REST API | HTTP 状态 201 表示请求成功创建了新资源。 | «是» Пояснение: HTTP 状态码 201 表示请求已成功,并且作为结果创建了新的资源。
Raw{"answer": "是", "解释": "HTTP 状态码 201 表示请求已成功,并且作为结果创建了新的资源。"} | верно | 201 Created; обычно на POST, часто с Location; RFC 9110. |
T19-L2 0.23 c | HTTP 与 REST API | 哪个 HTTP 状态表示请求成功且响应体为空(例如 DELETE 之后)? | «204» Пояснение: HTTP 204 No Content 表示请求成功且响应体为空。
Raw{"answer": "204", "解释": "HTTP 204 No Content 表示请求成功且响应体为空。"} | верно | 204 No Content; RFC 9110. |
T19-L3 0.45 c | HTTP 与 REST API | 按 HTTP 规范,DELETE 方法是幂等的:对同一资源重复请求不会改变结果。 | «是» Пояснение: 根据HTTP规范,DELETE方法被定义为幂等,重复请求同一资源应产生相同的结果,即多次请求的效果与一次请求相同。
Raw```json ⏎ {"answer": "是", "解释": "根据HTTP规范,DELETE方法被定义为幂等,重复请求同一资源应产生相同的结果,即多次请求的效果与一次请求相同。"} ⏎ ``` | верно | RFC 9110: DELETE идемпотентен (как PUT); идемпотентность ≠ безопасность — ресурс удаляется при первом вызове. |
T19-L4 0.42 c | HTTP 与 REST API | Access-Control-Allow-Origin 头是由客户端发送的,以便服务器同意接受来自其他源的请求。 | «否» Пояснение: Access-Control-Allow-Origin 头是由服务器发送的,用于告诉浏览器该服务器是否同意接受来自其他源的请求,而不是由客户端发送。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "Access-Control-Allow-Origin 头是由服务器发送的,用于告诉浏览器该服务器是否同意接受来自其他源的请求,而不是由客户端发送。" ⏎ } ⏎ ``` | верно | Наоборот: заголовок шлёт СЕРВЕР в ответе, разрешая браузеру cross-origin запрос (CORS); в проекте nelmio/cors-bundle. |
T19-L5 0.27 c | HTTP 与 REST API | 状态码 429 Too Many Requests 用于客户端超出请求频率限制(rate limiting)的情况。 | «是» Пояснение: HTTP 429 状态码明确表示客户端在给定时间内发送了过多的请求。
Raw{"answer": "是", "解释": "HTTP 429 状态码明确表示客户端在给定时间内发送了过多的请求。"} | верно | 429 (+ Retry-After); RFC 6585. В проекте symfony/rate-limiter. |
T19-L6 0.21 c | HTTP 与 REST API | 5xx 表示客户端错误,而 4xx 表示服务器端错误。 | «否» Пояснение: 4xx 表示客户端错误,5xx 表示服务器端错误。
Raw{"answer": "否", "解释": "4xx 表示客户端错误,5xx 表示服务器端错误。"} | верно | Наоборот: 4xx — ошибка клиента (400, 404), 5xx — сервера (500, 503); классы статусов RFC 9110. |
T19-L7 0.23 c | HTTP 与 REST API | 哪个 HTTP 头指明请求或响应体的 MIME 类型? | «content-type» Пояснение: Content-Type 头用于指明资源或请求体的媒体类型。
Raw{"answer": "Content-Type", "解释": "Content-Type 头用于指明资源或请求体的媒体类型。"} | верно | Content-Type: application/json и т.п. |
T19-L8 0.31 c | HTTP 与 REST API | 与 PUT 不同,按照 RFC 5789,PATCH 不要求幂等。 | «是» Пояснение: RFC 5789 中定义了 PATCH 方法,并指出 PATCH 不要求幂等。
Raw```json ⏎ {"answer": "是", "解释": "RFC 5789 中定义了 PATCH 方法,并指出 PATCH 不要求幂等。"} ⏎ ``` | верно | RFC 5789 прямо оговаривает: PATCH не гарантированно идемпотентен; PUT идемпотентен. |
T20-L1 0.54 c | 安全与 OAuth | 用普通 == 把密码的哈希与库中哈希比较就足以校验密码。 | «否» Пояснение: 使用 == 比较哈希可能会受到时间侧信道攻击(timing attack)的影响,且哈希值可能包含特殊字符导致类型转换问题,推荐使用 hash_equals() 进行安全比较。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "使用 == 比较哈希可能会受到时间侧信道攻击(timing attack)的影响,且哈希值可能包含特殊字符导致类型转换问题,推荐使用 hash_equals() 进行安全比较。" ⏎ } ⏎ ``` | верно | Нужна постоянновременная проверка (password_verify) — timing-атаки; соль и алгоритм уже внутри хеша. |
T20-L2 0.24 c | 安全与 OAuth | CSRF 令牌由服务器发放(绑定会话),并在 unsafe 请求(POST 等)时在服务器端校验。 | «是» Пояснение: 这是 CSRF 令牌机制的标准工作流程。
Raw{"answer": "是", "解释": "这是 CSRF 令牌机制的标准工作流程。"} | верно | symfony/security-csrf в проекте; защита от подделки межсайтовой формы. |
T20-L3 0.31 c | 安全与 OAuth | 哪个 HTTP 头用于启用 CSP(Content Security Policy)策略? | «content-security-policy» Пояснение: Content-Security-Policy HTTP 头用于定义 CSP 策略,以防止 XSS 等安全漏洞。
Raw{"answer": "Content-Security-Policy", "解释": "Content-Security-Policy HTTP 头用于定义 CSP 策略,以防止 XSS 等安全漏洞。"} | верно | Content-Security-Policy; белые списки источников скриптов/стилей против XSS. |
T20-L4 0.35 c | 安全与 OAuth | OAuth 2.0 是身份认证协议:access 令牌能说明用户是谁。 | «否» Пояснение: Access Token 用于授权(资源访问),OpenID Connect 或 ID Token 才用于身份认证(识别用户)。
Raw{"answer": "否", "解释": "Access Token 用于授权(资源访问),OpenID Connect 或 ID Token 才用于身份认证(识别用户)。"} | верно | OAuth 2.0 — авторизация/делегирование доступа; аутентификацию добавляет OpenID Connect. В проекте knpuniversity/oauth2-client-bundle (yandex/github/google). |
T20-L5 0.41 c | 安全与 OAuth | XSS 可以通过在写库前对输入做服务器端校验来防止。 | «否» Пояснение: XSS 主要依赖服务器端输出编码(Output Encoding)来防止,仅靠输入校验无法覆盖所有场景(如 DOM-based XSS 或编码差异)。
Raw{"answer": "否", "解释": "XSS 主要依赖服务器端输出编码(Output Encoding)来防止,仅靠输入校验无法覆盖所有场景(如 DOM-based XSS 或编码差异)。"} | верно | XSS лечится контекстным экранированием НА ВЫВОДЕ (Twig autoescape, CSP); валидация ввода не покрывает все контексты вывода. |
T20-L6 0.28 c | 安全与 OAuth | 在 OAuth 2.0 授权码流程中,哪个参数会回到 redirect_uri 并用于换取 access 令牌? | «code» Пояснение: 授权码流程中,授权服务器返回的 code 参数用于后续换取 access token。
Raw{"answer": "code", "解释": "授权码流程中,授权服务器返回的 code 参数用于后续换取 access token。"} | верно | Параметр code; обмен на токен POST-ом на /token с client_secret. |
T20-L7 0.31 c | 安全与 OAuth | Refresh 令牌的生命周期比 access 令牌长,可在用户不重新登录的情况下换取新的 access 令牌。 | «是» Пояснение: refresh token 的生命周期通常比 access token 更长,用于在 access token 过期后无感刷新认证状态。
Raw{ ⏎ "answer": "是", ⏎ "解释": "refresh token 的生命周期通常比 access token 更长,用于在 access token 过期后无感刷新认证状态。" ⏎ } | верно | Стандартная схема OAuth/OIDC: короткий access + длинный refresh. |
T20-L8 0.47 c | 安全与 OAuth | 密码盐必须保密:没有盐就无法校验哈希。 | «否» Пояснение: 在现代密码学中(如 PBKDF2, bcrypt, Argon2),盐值通常与哈希值一起存储(通常是明文或编码后),无需保密,只需保证唯一性。
Raw{"answer": "否", "解释": "在现代密码学中(如 PBKDF2, bcrypt, Argon2),盐值通常与哈希值一起存储(通常是明文或编码后),无需保密,只需保证唯一性。"} | верно | Соль хранится открыто (password_hash включает её в строку хеша); секретность соли не нужна. |
T18-L1 0.33 c | 测试:PHPUnit | PHPUnit 会执行任何类的测试方法——不必继承 TestCase。 | «否» Пояснение: PHPUnit 的测试类通常需要继承 PHPUnit\Framework\TestCase 才能使用其提供的断言和测试功能。
Raw```json ⏎ {"answer": "否", "解释": "PHPUnit 的测试类通常需要继承 PHPUnit\\Framework\\TestCase 才能使用其提供的断言和测试功能。"} ⏎ ``` | верно | Тестом считается метод класса, наследующего TestCase (PHPUnit 10). |
T18-L2 0.33 c | 测试:PHPUnit | PHPUnit 的 setUp() 在类的所有测试之前只执行一次。 | «否» Пояснение: PHPUnit 的 setUp() 在每次执行测试方法前都会调用,而不是所有测试只执行一次。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "PHPUnit 的 setUp() 在每次执行测试方法前都会调用,而不是所有测试只执行一次。" ⏎ } ⏎ ``` | верно | setUp() — перед КАЖДЫМ тестом; один раз на класс — setUpBeforeClass(). Проверено живым счётчиком на PHPUnit 10.5. |
T18-L3 0.27 c | 测试:PHPUnit | 数据提供者(data provider)只允许用一组参数运行测试。 | «否» Пояснение: 数据提供者允许为同一测试方法运行多组不同的参数组合。
Raw{"answer": "否", "解释": "数据提供者允许为同一测试方法运行多组不同的参数组合。"} | верно | Наоборот: наборов может быть сколько угодно — тест выполняется по разу на каждый. Проверено на PHPUnit 10.5 (#[DataProvider]). |
T18-L4 0.21 c | 测试:PHPUnit | PHPUnit 的哪个方法用于声明期望抛出某个特定类的异常? | «expectexception» Пояснение: PHPUnit 使用 expectException() 方法声明期望抛出指定类的异常。
Raw{"answer": "expectException", "解释": "PHPUnit 使用 expectException() 方法声明期望抛出指定类的异常。"} | верно | $this->expectException(\LogicException::class); проверено на PHPUnit 10.5. |
T18-L5 0.34 c | 测试:PHPUnit | 在 PHPUnit 中,stub(桩)检查哪些方法被调用过,而 mock(模拟对象)只是返回数据。 | «否» Пояснение: 在 PHPUnit 中,Mock(模拟对象)用于检查方法的调用,而 Stub(桩)用于返回预设数据。
Raw```json ⏎ { ⏎ "answer": "否", ⏎ "解释": "在 PHPUnit 中,Mock(模拟对象)用于检查方法的调用,而 Stub(桩)用于返回预设数据。" ⏎ } ⏎ ``` | верно | Наоборот: стаб подставляет данные, мок проверяет взаимодействия (createStub/createMock); docs PHPUnit — Test Doubles. |
T18-L6 0.26 c | 测试:PHPUnit | 在 PHPUnit 10+ 中,向测试传递数据的推荐方式是 #[DataProvider] 属性(@dataProvider 注解已弃用)。 | «是» Пояснение: PHPUnit 10+ 推荐使用 #[DataProvider] 属性替代已弃用的 @dataProvider 注解。
Raw{"answer": "是", "解释": "PHPUnit 10+ 推荐使用 #[DataProvider] 属性替代已弃用的 @dataProvider 注解。"} | верно | Аннотация ещё парсится в PHPUnit 10/11 (AnnotationParser в 10.5.66), удаление — в 12; атрибут — стандарт. |
T18-L7 0.27 c | 测试:PHPUnit | PHPUnit 不允许声明一个测试依赖于另一个测试的结果。 | «否» Пояснение: PHPUnit 允许通过 @depends 注解声明测试之间的依赖关系。
Raw```json ⏎ {"answer": "否", "解释": "PHPUnit 允许通过 @depends 注解声明测试之间的依赖关系。"} ⏎ ``` | верно | Зависимости есть: #[Depends] — зависимый тест не запустится, еслиProducer упал. |
T18-L8 0.29 c | 测试:PHPUnit | PHPUnit 的哪个命令行选项会让测试以随机顺序执行? | «--order-by=random» Пояснение: 该选项用于指定测试用例以随机顺序执行。
Raw{"answer": "--order-by=random", "解释": "该选项用于指定测试用例以随机顺序执行。"} | верно | --order-by=random (PHPUnit 9+); опция есть в --help PHPUnit 10.5 (проектная). |
T01-L9 3.21 c | 语法与运算符 | 这段代码会输出什么?
```php
echo intdiv(7, 2) . intdiv(-7, 2);
``` | «3-3» Пояснение: intdiv(7, 2) 为 3,intdiv(-7, 2) 为 -3,拼接后输出 "3-3"。
Raw{"answer": "3-3", "解释": "intdiv(7, 2) 为 3,intdiv(-7, 2) 为 -3,拼接后输出 \"3-3\"。"} | верно | intdiv 向零截断:intdiv(-7, 2) = -3,不是 -4。 |
T01-L10 0.77 c | 语法与运算符 | 这段代码会输出什么?
```php
echo -3 ** 2;
``` | «9» Пояснение: 在 PHP 中,`**` 运算符具有比一元负号更高的优先级,因此 `-3 ** 2` 被解析为 `-(3 ** 2)`,即 `-(9)`,结果为 -9。等等,我刚才看错了,是 -9。让我再确认一下:`**` 优先级确实比一元负号高,所以是 `-(3**2)` = -9。
Raw{"answer": 9, "解释": "在 PHP 中,`**` 运算符具有比一元负号更高的优先级,因此 `-3 ** 2` 被解析为 `-(3 ** 2)`,即 `-(9)`,结果为 -9。等等,我刚才看错了,是 -9。让我再确认一下:`**` 优先级确实比一元负号高,所以是 `-(3**2)` = -9。"} | неверно верный: «-9» | ** 右结合且优先级高于一元负号:-(3²)。 |
T02-L9 0.5 c | 类型与比较 | 这段代码会输出什么?
```php
echo '1e1' == '10' ? 'true' : 'false';
``` | «true» Пояснение: 在 PHP 中,'1e1' 被解释为浮点数 10,与字符串 '10' 比较时,'10' 也被解释为数值 10,因此两者相等。
Raw{"answer": "true", "解释": "在 PHP 中,'1e1' 被解释为浮点数 10,与字符串 '10' 比较时,'10' 也被解释为数值 10,因此两者相等。"} | верно | 两个字符串都是数值型——按数字比较:10 == 10。 |
T02-L10 0.34 c | 类型与比较 | 这段代码会输出什么?
```php
switch ('a') {
case 0: echo 'zero'; break;
default: echo 'other';
}
``` | «other» Пояснение: switch 使用弱类型比较,'a' 转换为 0 匹配 case 0,输出 zero。
Raw{"answer": "other", "解释": "switch 使用弱类型比较,'a' 转换为 0 匹配 case 0,输出 zero。"} | верно | PHP 8:'a' == 0 → false(以前是 true)——触发 default。 |
T03-L9 0.44 c | 字符串 | 这段代码会输出什么?
```php
echo strtr('abc', ['a' => '1', 'ab' => '2']);
``` | «2c» Пояснение: strtr 中数组形式的查找替换,优先匹配较长的字符串 'ab',故 'ab' 被替换为 '2','c' 不变。
Raw{"answer": "2c", "解释": "strtr 中数组形式的查找替换,优先匹配较长的字符串 'ab',故 'ab' 被替换为 '2','c' 不变。"} | верно | 带数组的 strtr 优先匹配最长的键。 |
T03-L10 0.26 c | 字符串 | 这段代码会输出什么?
```php
echo '[' . substr('hello', -10) . ']';
``` | «[hello]» Пояснение: substr 在偏移量超出字符串长度时返回整个字符串。
Raw{"answer": "[hello]", "解释": "substr 在偏移量超出字符串长度时返回整个字符串。"} | верно | 超出字符串范围的负起始位置会被钳制到开头。 |
T04-L9 0.34 c | 数组 | 这段代码会输出什么?
```php
$a = ['k' => 1, 'n' => 2];
$b = ['k' => 9, 'm' => 3];
echo implode(',', array_keys($a + $b));
``` | «k,n,m» Пояснение: 数组合并操作符 + 保留左数组的键,合并后键为 k, n, m。
Raw{"answer": "k,n,m", "解释": "数组合并操作符 + 保留左数组的键,合并后键为 k, n, m。"} | верно | 运算符 +:字符串键重复时左数组优先。 |
T04-L10 0.26 c | 数组 | 这段代码会输出什么?
```php
$a = [[1, 'x', 2], [2, 'y', 1], [3, 'z', 2]];
usort($a, fn($p, $q) => $p[2] <=> $q[2]);
echo implode('', array_column($a, 1));
``` | «xyz» Пояснение: 按第三个元素稳定排序后取第二列拼接
Raw{"answer": "xyz", "解释": "按第三个元素稳定排序后取第二列拼接"} | неверно верный: «yxz» | 自 8.0 起排序稳定:键相同时 x 和 z 保持原顺序。 |
T05-L10 3.36 c | 函数与闭包 | 这段代码会输出什么?
```php
function f(int $a, int $b): int
{
return $a - $b;
}
echo f(...['b' => 1, 'a' => 5]);
``` | «4» Пояснение: 使用命名参数展开时,'b' => 1 和 'a' => 5 会正确映射到函数参数,因此 f(5, 1) 返回 4。
Raw{"answer": 4, "解释": "使用命名参数展开时,'b' => 1 和 'a' => 5 会正确映射到函数参数,因此 f(5, 1) 返回 4。"} | верно | 展开数组的字符串键会成为命名参数。 |
T05-L9 0.58 c | 函数与闭包 | 这段代码会输出什么?
```php
class P
{
private int $v = 3;
public function g(): int { return $this->v; }
}
$p = new P;
$f = $p->g(...);
$p = null;
echo $f();
``` | «3» Пояснение: 闭包 $f 捕获了对象 $p 的引用,尽管 $p 被设为 null,但闭包内部仍然持有对象的引用,调用 $f() 时对象仍存活,返回其属性值 3。
Raw{"answer": 3, "解释": "闭包 $f 捕获了对象 $p 的引用,尽管 $p 被设为 null,但闭包内部仍然持有对象的引用,调用 $f() 时对象仍存活,返回其属性值 3。"} | верно | 一等可调用语法在创建时就绑定了 $this。 |
T06-L9 0.27 c | OOP:类与继承 | 这段代码会输出什么?
```php
class A
{
public function who(): string { return static::class; }
}
class B extends A {}
echo (new B)->who();
``` | «b» Пояснение: static::class 返回调用该方法的实际类名,即 B。
Raw{"answer": "B", "解释": "static::class 返回调用该方法的实际类名,即 B。"} | верно | 后期静态绑定:static::class 是接收者的类。 |
T06-L10 0.43 c | OOP:类与继承 | 这段代码在 PHP 8.5 上会输出什么?
```php
class C
{
public int $x = 0 {
set { $this->x = $value * 2; }
}
}
$c = new C;
$c->x = 5;
echo $c->x;
``` | «10» Пояснение: PHP 8.4 支持属性的初始值,set 方法中 $value * 2 将 5 变为 10。
Raw{"answer": 10, "解释": "PHP 8.4 支持属性的初始值,set 方法中 $value * 2 将 5 变为 10。"} | верно | 在 set 钩子内 $this->x 写入后备存储(无递归):5*2。 |
T07-L9 0.41 c | 接口、trait 与 enum | 这段代码会输出什么?
```php
trait TA
{
public function f(): string { return 'A'; }
}
trait TB
{
public function f(): string { return 'B'; }
}
class TC
{
use TA, TB { TB::f insteadof TA; TA::f as g; }
}
echo (new TC)->f() . (new TC)->g();
``` | «ba» Пояснение: insteadof 使 TB::f 取代 TA::f,as g 将 TA::f 重命名为 g,因此 f() 返回 'B',g() 返回 'A'。
Raw{"answer": "BA", "解释": "insteadof 使 TB::f 取代 TA::f,as g 将 TA::f 重命名为 g,因此 f() 返回 'B',g() 返回 'A'。"} | верно | insteadof 选择实现,as 以别名保留另一个。 |
T07-L10 0.42 c | 接口、trait 与 enum | 这段代码会输出什么?
```php
trait Counter
{
public static int $n = 0;
}
class CX { use Counter; }
class CY { use Counter; }
CX::$n = 1;
echo CY::$n;
``` | «1» Пояснение: Trait中的静态属性在每个使用该trait的类中是独立的实例,CX和CY分别维护自己的$n。
Raw{"answer": "1", "解释": "Trait中的静态属性在每个使用该trait的类中是独立的实例,CX和CY分别维护自己的$n。"} | неверно верный: «0» | trait 的静态属性会复制到每个使用它的类中。 |
T08-L10 0.38 c | 异常与错误 | 这段代码会输出什么?
```php
function f(): int
{
try { return 1; } finally { return 2; }
}
echo f();
``` | «2» Пояснение: PHP 8.0 之前,finally 块的 return 会覆盖 try 块的返回值,因此输出为 2。
Raw{"answer": 2, "解释": "PHP 8.0 之前,finally 块的 return 会覆盖 try 块的返回值,因此输出为 2。"} | верно | finally 中的 return 会覆盖 try 中的 return。 |
T08-L9 0.3 c | 异常与错误 | 这段代码会输出什么?
```php
try {
try {
throw new RuntimeException('first');
} finally {
throw new LogicException('second');
}
} catch (LogicException $e) {
echo $e->getMessage();
}
``` | «second» Пояснение: finally 块中抛出的新异常会覆盖 try 块中未捕获的异常,由外层 catch 捕获并输出。
Raw{"answer": "second", "解释": "finally 块中抛出的新异常会覆盖 try 块中未捕获的异常,由外层 catch 捕获并输出。"} | верно | finally 抛出的异常会替换正在传播的异常——捕获最后抛出的那个。 |
T09-L9 0.39 c | 命名空间与自动加载 | 这段代码会输出什么?
```php
namespace N;
use App\Foo as Baz;
echo Baz::class . '|' . \Baz::class;
``` | «app\foo|baz» Пояснение: Baz::class 解析为别名对应的 App\Foo,而 \Baz::class 解析为根命名空间的 Baz。
Raw{"answer": "App\\Foo|Baz", "解释": "Baz::class 解析为别名对应的 App\\Foo,而 \\Baz::class 解析为根命名空间的 Baz。"} | верно | use 别名只作用于非限定名;前导 \ 转向全局作用域。 |
T09-L10 0.49 c | 命名空间与自动加载 | 这段代码会输出什么?
```php
namespace Ns;
class Foo {}
$c = 'Foo';
echo (class_exists($c) ? 'yes' : 'no')
. (class_exists(__NAMESPACE__ . '\\' . $c) ? 'yes' : 'no');
``` | «yesyes» Пояснение: class_exists('Foo') 在默认情况下会在当前命名空间中查找,因此 'Foo' 被找到;而 class_exists('Ns\Foo') 也会成功找到,因为 __NAMESPACE__ 为 'Ns'。
Raw{"answer": "yesyes", "解释": "class_exists('Foo') 在默认情况下会在当前命名空间中查找,因此 'Foo' 被找到;而 class_exists('Ns\\Foo') 也会成功找到,因为 __NAMESPACE__ 为 'Ns'。"} | неверно верный: «noyes» | 动态名称不会相对于命名空间解析——'Foo' 指全局类。 |
T10-L9 0.43 c | 引用与作用域 | 这段代码会输出什么?
```php
$a = [1, 2, 3];
foreach ($a as &$v) {}
$v = 99;
echo implode(',', $a);
``` | «1,2,99» Пояснение: foreach by reference 使得 $v 指向 $a 的最后一个元素,赋值 $v=99 修改了 $a[2]。
Raw{"answer": "1,2,99", "解释": "foreach by reference 使得 $v 指向 $a 的最后一个元素,赋值 $v=99 修改了 $a[2]。"} | верно | 按引用的 foreach 结束后,$v 仍是对最后一个元素的引用。 |
T10-L10 0.4 c | 引用与作用域 | 这段代码会输出什么?
```php
class A
{
public function inc(): int
{
static $n = 0;
return ++$n;
}
}
class B extends A {}
$a = new A;
$b = new B;
$a->inc();
$b->inc();
echo $a->inc();
``` | «3» Пояснение: static 变量在类层次结构中共享,每次调用 inc() 时 $n 递增。
Raw{"answer": 3, "解释": "static 变量在类层次结构中共享,每次调用 inc() 时 $n 递增。"} | верно | 方法的静态变量属于父类方法——子类共享同一个。 |
T11-L9 0.43 c | 生成器、迭代器与 SPL | 这段代码会输出什么?
```php
function g(): Generator
{
$x = yield 1;
return $x + 1;
}
$g = g();
$g->send(10);
echo $g->getReturn();
``` | «11» Пояснение: send(10) 将 10 赋给 $x,生成器返回 10 + 1 = 11,getReturn() 获取该返回值。
Raw{"answer": 11, "解释": "send(10) 将 10 赋给 $x,生成器返回 10 + 1 = 11,getReturn() 获取该返回值。"} | верно | send() 恢复生成器:$x = 10,return 10+1。 |
T11-L10 0.51 c | 生成器、迭代器与 SPL | 这段代码会输出什么?
```php
function inner(): Generator
{
yield 1;
yield 2;
return 'ok';
}
function outer(): Generator
{
$r = yield from inner();
yield $r;
}
echo implode(',', iterator_to_array(outer()));
``` | «1,2,ok» Пояснение: yield from 会转发内部生成器的值(1,2),并将内部生成器 return 的值('ok')赋给 $r,最后 yield $r 输出 'ok'。
Raw{"answer": "1,2,ok", "解释": "yield from 会转发内部生成器的值(1,2),并将内部生成器 return 的值('ok')赋给 $r,最后 yield $r 输出 'ok'。"} | неверно верный: «ok,2» | yield from 不推进外层自动键:yield $r 得到键 0 并覆盖 1——'ok' 排在最前面。 |
T12-L9 0.42 c | 配置与安全 | 这段代码会输出什么?
```php
$hash = password_hash('x', PASSWORD_BCRYPT, ['cost' => 4]);
echo password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 4]) ? 'yes' : 'no';
echo password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 5]) ? 'yes' : 'no';
``` | «noyes» Пояснение: 第一次调用成本为4且已匹配,返回no;第二次调用成本为5不匹配,返回yes。
Raw{"answer": "noyes", "解释": "第一次调用成本为4且已匹配,返回no;第二次调用成本为5不匹配,返回yes。"} | верно | password_needs_rehash 比较哈希参数与目标:cost 4 = 4 → 'no',cost 5 ≠ 4 → 'yes'。 |
T12-L10 0.43 c | 配置与安全 | 这段代码在 PHP 8.5 上会输出什么?
```php
echo (E_ALL & 2048) === 0 ? 'strict-out' : 'strict-in';
``` | «strict-out» Пояснение: E_ALL (4096) 与 2048 按位与结果为 0,因此表达式为 true,输出 'strict-out'。
Raw```json ⏎ {"answer": "strict-out", "解释": "E_ALL (4096) 与 2048 按位与结果为 0,因此表达式为 true,输出 'strict-out'。"} ⏎ ``` | верно | PHP 8.4+ 将 E_STRICT 移出了 E_ALL:2048 位未设置 → 'strict-out'(2048 是历史上的 E_STRICT 位)。 |
T13-L9 0.27 c | Symfony | 这段代码会输出什么?
```php
use Symfony\Component\HttpFoundation\Request;
$r = Request::create('/demo', 'GET', [], [], [], ['HTTP_X_TOKEN' => 'abc']);
echo $r->headers->get('X-Token') === 'abc' ? 'mapped' : 'missing';
``` | «mapped» Пояснение: Symfony 自动将 HTTP_X_TOKEN 映射为 X-Token 头。
Raw{"answer": "mapped", "解释": "Symfony 自动将 HTTP_X_TOKEN 映射为 X-Token 头。"} | верно | 与字面量的比较需要知道映射规则:HttpFoundation 把 HTTP_X_TOKEN 转换为 X-Token 头(大小写不敏感);不知道映射会答 'missing'。 |
T13-L10 1.41 c | Symfony | 这段代码会输出什么?
```php
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Contracts\EventDispatcher\Event;
$d = new EventDispatcher();
$out = '';
$d->addListener('e', function () use (&$out) { $out .= 'B'; }, 10);
$d->addListener('e', function () use (&$out) { $out .= 'A'; });
$d->addListener('e', function () use (&$out) { $out .= 'C'; }, 5);
$d->dispatch(new Event(), 'e');
echo $out;
``` | «ba» Пояснение: Symfony EventDispatcher 默认按注册顺序调用监听器,优先级(priority)参数仅用于确定插入位置,默认优先级为 0,因此按 A(0), B(10), C(5) 的插入逻辑,实际调用顺序为 C(5), B(10), A(0),但题目中优先级仅影响插入位置而非执行顺序,Symfony 中优先级高的先执行,故为 B, C, A;但注意:Symfony 的 addListener 中 priority 参数越小越后执行,默认 0,优先级高的先执行,所以顺序是 B(10) > C(5) > A(0),输出 'BCA'。
Raw{"answer": "BA", "解释": "Symfony EventDispatcher 默认按注册顺序调用监听器,优先级(priority)参数仅用于确定插入位置,默认优先级为 0,因此按 A(0), B(10), C(5) 的插入逻辑,实际调用顺序为 C(5), B(10), A(0),但题目中优先级仅影响插入位置而非执行顺序,Symfony 中优先级高的先执行,故为 B, C, A;但注意:Symfony 的 addListener 中 priority 参数越小越后执行,默认 0,优先级高的先执行,所以顺序是 B(10) > C(5) > A(0),输出 'BCA'。"} | неверно верный: «bca» | 监听器按优先级降序执行:10 (B)、5 (C)、0 (A)。 |
T14-L10 0.8 c | Doctrine | 给定:Doctrine ORM 3,EntityManager 使用内存 SQLite,实体 User 带自增主键。users 表为空。这段代码会输出什么?
```php
$u = new User(name: 'A');
$em->persist($u);
$em->flush();
$a = $em->find(User::class, $u->getId());
$b = $em->find(User::class, $u->getId());
echo spl_object_id($a) === spl_object_id($b) ? 'same' : 'diff';
``` | «same» Пояснение: EntityManager 维护了一个 Identity Map(同一性映射),当通过 find 方法查找同一个实体 ID 时,它会返回之前已经加载并缓存的实体实例,而不是每次都创建新的对象。因此,$a 和 $b 指向的是内存中同一个 User 对象,spl_object_id 相同。
Raw{"answer": "same", "解释": "EntityManager 维护了一个 Identity Map(同一性映射),当通过 find 方法查找同一个实体 ID 时,它会返回之前已经加载并缓存的实体实例,而不是每次都创建新的对象。因此,$a 和 $b 指向的是内存中同一个 User 对象,spl_object_id 相同。"} | верно | identity map:对同一 id 的再次 find 返回同一个实例。 |
T14-L9 0.42 c | Doctrine | 给定:Doctrine ORM 3,EntityManager 使用内存 SQLite,实体 User 带自增主键。users 表为空。这段代码会输出什么?
```php
$u = new User(name: 'B');
$em->persist($u);
$em->remove($u);
$em->flush();
echo count($em->getConnection()->fetchAllAssociative('SELECT * FROM users'));
``` | «0» Пояснение: Doctrine ORM 在 flush 之前对同一实体执行 persist 和 remove,最终状态为 removed,不会生成 INSERT 语句。
Raw```json ⏎ { ⏎ "answer": 0, ⏎ "解释": "Doctrine ORM 在 flush 之前对同一实体执行 persist 和 remove,最终状态为 removed,不会生成 INSERT 语句。" ⏎ } ⏎ ``` | верно | 工作单元在 flush 时才安排 INSERT:persist 后 remove 会取消插入。 |
T15-L10 0.27 c | PostgreSQL | 这个 SQL 查询返回什么(PostgreSQL 17)?
```sql
CREATE TEMP TABLE t (x int);
INSERT INTO t VALUES (1), (NULL);
SELECT count(x) FROM t;
``` | «1» Пояснение: count(x) 只统计非 NULL 的值,因此返回 1。
Raw{"answer": 1, "解释": "count(x) 只统计非 NULL 的值,因此返回 1。"} | верно | count(列) 不计 NULL;count(*) 会返回 2。 |
T15-L9 0.57 c | PostgreSQL | 这个 SQL 查询返回什么(PostgreSQL 17)?
```sql
CREATE TEMP TABLE t (id int, x int);
INSERT INTO t VALUES (1, 10), (2, 20), (3, 30);
SELECT string_agg(s::text, ',' ORDER BY id) FROM (
SELECT id, sum(x) OVER (ORDER BY id) AS s FROM t
) q;
``` | «10,30,60» Пояснение: 窗口函数 sum(x) OVER (ORDER BY id) 按 id 排序计算累积和,分别为 10, 30, 60,string_agg 按 id 顺序用逗号拼接得到 '10,30,60'。
Raw{"answer": "10,30,60", "解释": "窗口函数 sum(x) OVER (ORDER BY id) 按 id 排序计算累积和,分别为 10, 30, 60,string_agg 按 id 顺序用逗号拼接得到 '10,30,60'。"} | верно | 有 ORDER BY 时窗口默认帧是 running(从起点到当前行)。 |
T16-L9 0.41 c | Symfony:Messenger | 这段代码会输出什么?
```php
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Symfony\Component\Messenger\Envelope;
final class Trace implements MiddlewareInterface
{
public function __construct(private string $tag) {}
public function handle(Envelope $e, StackInterface $stack): Envelope
{
echo $this->tag;
return $stack->next()->handle($e, $stack);
}
}
$bus = new MessageBus([new Trace('M1'), new Trace('M2')]);
$bus->dispatch(new Envelope(new stdClass()));
``` | «m1m2» Пояснение: 中间件链依次执行,第一个中间件输出'M1',第二个中间件输出'M2'。
Raw{"answer": "M1M2", "解释": "中间件链依次执行,第一个中间件输出'M1',第二个中间件输出'M2'。"} | верно | 先添加的中间件先执行(最外层)。 |
T16-L10 0.37 c | Symfony:Messenger | 这段代码会输出什么?
```php
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;
use Symfony\Component\Messenger\Handler\HandlersLocator;
use Symfony\Component\Messenger\Handler\HandlerDescriptor;
use Symfony\Component\Messenger\Envelope;
class Ping {}
$n = 0;
$d1 = new HandlerDescriptor(function (Ping $m) use (&$n) { $n += 1; }, ['alias' => 'h1']);
$d2 = new HandlerDescriptor(function (Ping $m) use (&$n) { $n += 10; }, ['alias' => 'h2']);
$bus = new MessageBus([
new HandleMessageMiddleware(new HandlersLocator([Ping::class => [$d1, $d2]])),
]);
$bus->dispatch(new Envelope(new Ping()));
echo $n;
``` | «11» Пояснение: 两个处理器都被调用,n 分别增加 1 和 10,最终为 11。
Raw{"answer": 11, "解释": "两个处理器都被调用,n 分别增加 1 和 10,最终为 11。"} | верно | 消息的所有已注册处理器都会执行:1 + 10 = 11。 |
T17-L9 0.33 c | PostgreSQL:事务与索引 | 这个 SQL 查询返回什么(PostgreSQL 17)?
```sql
CREATE TEMP TABLE t (a int);
CREATE UNIQUE INDEX ON t (a);
INSERT INTO t VALUES (1) ON CONFLICT DO NOTHING;
INSERT INTO t VALUES (1) ON CONFLICT DO NOTHING;
SELECT count(*) FROM t;
``` | «1» Пояснение: 唯一索引防止重复插入,表中有1条记录。
Raw```json ⏎ {"answer": 1, "解释": "唯一索引防止重复插入,表中有1条记录。"} ⏎ ``` | верно | ON CONFLICT DO NOTHING 跳过重复:只插入一行。 |
T17-L10 0.44 c | PostgreSQL:事务与索引 | 这组 psql 命令会输出什么?
```sql
BEGIN;
CREATE TEMP TABLE t (a int, UNIQUE (a) DEFERRABLE INITIALLY DEFERRED);
INSERT INTO t VALUES (1);
INSERT INTO t VALUES (1);
SELECT count(*) FROM t;
``` | «2» Пояснение: 因为 UNIQUE 约束是 DEFERRABLE 且 INITIALLY DEFERRED,冲突检查推迟到事务结束,所以两次插入都成功,计数为2。
Raw{"answer": 2, "解释": "因为 UNIQUE 约束是 DEFERRABLE 且 INITIALLY DEFERRED,冲突检查推迟到事务结束,所以两次插入都成功,计数为2。"} | верно | DEFERRED 把唯一性检查推迟到 COMMIT——count 看到 2 行。 |
T18-L9 0.38 c | 测试:PHPUnit | 这条命令会执行多少个测试?
```php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
final class CalcTest extends TestCase
{
public static function prov(): array
{
return [[1], [2], [3]];
}
#[DataProvider('prov')]
public function test_sum(int $x): void
{
$this->assertTrue($x > 0);
}
#[DataProvider('prov')]
public function test_sum_abs(int $x): void
{
$this->assertTrue($x > 0);
}
public function test_other(): void
{
$this->assertTrue(true);
}
}
```
命令:`phpunit CalcTest.php --filter test_sum`(PHPUnit 10.5) | «6» Пояснение: filter 匹配 test_sum 和 test_sum_abs,每个测试有 3 组数据,共 6 个用例。
Raw{"answer": 6, "解释": "filter 匹配 test_sum 和 test_sum_abs,每个测试有 3 组数据,共 6 个用例。"} | верно | --filter 是子串匹配:test_sum 也会匹配 test_sum_abs(3+3 个数据集)。 |
T18-L10 0.39 c | 测试:PHPUnit | 这条命令会执行多少个测试,其中多少个失败(failure)?用逗号分隔的两个数字回答(执行数, 失败数)。
```php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
final class Calc2Test extends TestCase
{
public function prov(): array
{
return [[1], [-1]];
}
#[DataProvider('prov')]
public function test_x(int $x): void
{
$this->assertTrue($x > 0);
}
}
```
命令:`phpunit Calc2Test.php`(PHPUnit 10.5) | «2,1» Пояснение: 数据提供器返回两组数据,执行 2 次测试,其中 -1 使断言失败。
Raw{"answer": "2,1", "解释": "数据提供器返回两组数据,执行 2 次测试,其中 -1 使断言失败。"} | верно | 在 PHPUnit 10 中非静态 provider 只是 deprecation:两个数据集都会执行,[-1] 数据集断言失败——执行 2 个,失败 1 个。 |
T19-L9 0.29 c | HTTP 与 REST API | 这条命令发送哪个 HTTP 方法?
```bash
curl -s -d 'a=1' http://demo.local/api
``` | «post» Пояснение: curl 的 -d 选项默认使用 POST 方法发送请求。
Raw{"answer": "POST", "解释": "curl 的 -d 选项默认使用 POST 方法发送请求。"} | верно | -d/-F 会让 curl 默认使用 POST。 |
T19-L10 0.34 c | HTTP 与 REST API | 这条命令发送哪个 HTTP 方法?
```bash
curl -s -G -d 'a=1' http://demo.local/api
``` | «get» Пояснение: -G 标志将 -d 数据附加到 URL 查询字符串,发送 GET 请求。
Raw```json ⏎ {"answer": "GET", "解释": "-G 标志将 -d 数据附加到 URL 查询字符串,发送 GET 请求。"} | верно | -G 把 -d 的数据变成查询串,方法仍是 GET。 |
T20-L9 0.36 c | 安全与 OAuth | 客户端用不存在的 client_id 请求令牌端点(RFC 6749)。端点的 error 字段返回什么值? | «invalid_client» Пояснение: 根据 RFC 6749,当客户端标识符无效或缺失时,授权服务器应返回 invalid_client 错误。
Raw{"answer": "invalid_client", "解释": "根据 RFC 6749,当客户端标识符无效或缺失时,授权服务器应返回 invalid_client 错误。"} | верно | 未知客户端 → invalid_client(RFC 6749 §5.2)。 |
T20-L10 0.4 c | 安全与 OAuth | OAuth 2.0:客户端以 response_type=token 开始流程。授权服务器把 access_token 放在 redirect_uri 的哪个部分? | «fragment» Пояснение: 根据 OAuth 2.0 规范,隐式授权流程中的 access_token 通过 URL fragment(#token=...)返回,以避免记录在服务器日志中。
Raw{"answer": "fragment", "解释": "根据 OAuth 2.0 规范,隐式授权流程中的 access_token 通过 URL fragment(#token=...)返回,以避免记录在服务器日志中。"} | верно | 隐式流通过 URL 片段(#)传递令牌——它不会到达服务器。 |
T21-L9 0.46 c | Twig | 这个 Twig 模板会输出什么?
```twig
{{ false|default(2) * 3 }}
``` | «0» Пояснение: false|default(2) 结果是 false(因为 false 不是 null),false * 3 在 Twig 中为 0
Raw{"answer": 0, "解释": "false|default(2) 结果是 false(因为 false 不是 null),false * 3 在 Twig 中为 0"} | неверно верный: «6» | default 只替换 exactly false/null/''/[]——false 会变成 2,2*3 = 6;天真的「default 只用于 undefined」会得到 0。 |
T21-L10 0.46 c | Twig | 渲染这个模板时 render() 会抛出哪个异常类?
```twig
{{ 'a' ~ 1 + 2 }}
``` | «a12» Пояснение: Twig 中 `~` 是字符串连接运算符,优先级低于 `+`,因此先执行 `1 + 2` 得到 `3`,再与 `'a'` 连接得到 `'a3'`。
Raw{"answer": "a12", "解释": "Twig 中 `~` 是字符串连接运算符,优先级低于 `+`,因此先执行 `1 + 2` 得到 `3`,再与 `'a'` 连接得到 `'a3'`。"} | неверно верный: «runtimeerror» | 在 Twig 中 ~ 的优先级高于 +:('a' ~ 1) + 2 → string + int → 渲染错误(RuntimeError)。 |
T22-L9 0.88 c | Symfony:安全与表单 | 这段代码会输出什么?
```php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
$v = Validation::createValidator();
echo count($v->validate([''], [new Assert\NotBlank()]));
``` | «0» Пояснение: 数组 `['']` 只有一个空字符串元素,但 `NotBlank` 约束对数组的检查会检查每个元素,而 `''` 是空字符串,所以会触发一个验证错误。但这里 `validate` 方法返回的是 `ConstraintViolationList`,`count` 会统计错误数量,因此结果是 1。
Raw{"answer": 0, "解释": "数组 `['']` 只有一个空字符串元素,但 `NotBlank` 约束对数组的检查会检查每个元素,而 `''` 是空字符串,所以会触发一个验证错误。但这里 `validate` 方法返回的是 `ConstraintViolationList`,`count` 会统计错误数量,因此结果是 1。"} | верно | NotBlank 把 null、''、[] 视为空——数组 [''] 不算空。 |
T22-L10 0.39 c | Symfony:安全与表单 | 这段代码会输出什么?
```php
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\Extension\Core\Type\TextType;
$factory = Forms::createFormFactoryBuilder()->getFormFactory();
$form = $factory->create(TextType::class);
try {
echo $form->isValid() ? 'valid' : 'invalid';
} catch (Throwable $e) {
echo get_class($e);
}
``` | «invalid» Пояснение: 空表单在默认情况下验证失败,返回 invalid。
Raw```json ⏎ { ⏎ "answer": "invalid", ⏎ "解释": "空表单在默认情况下验证失败,返回 invalid。" ⏎ } ⏎ ``` | неверно верный: «symfony\component\form\exception\logicexception» | 对未提交的表单调用 isValid() 抛出 LogicException,而不是返回 false。 |
T23-L9 0.48 c | Symfony:配置与服务 | 这段代码会输出什么?
```php
use Symfony\Component\DependencyInjection\ContainerBuilder;
$c = new ContainerBuilder();
$c->register('a', stdClass::class)->setPublic(true);
$c->compile();
echo spl_object_id($c->get('a')) === spl_object_id($c->get('a')) ? 'same' : 'diff';
``` | «same» Пояснение: Symfony Container 中,同一服务的多次 get() 调用默认返回同一个实例(单例模式),因此 spl_object_id 相等,输出 'same'。
Raw{"answer": "same", "解释": "Symfony Container 中,同一服务的多次 get() 调用默认返回同一个实例(单例模式),因此 spl_object_id 相等,输出 'same'。"} | верно | 容器中的服务是共享的:两次 get() 得到同一实例。 |
T23-L10 0.31 c | Symfony:配置与服务 | 这段代码会输出什么?
```php
use Symfony\Component\DependencyInjection\ContainerBuilder;
$c = new ContainerBuilder();
$c->setParameter('name', 'Bob');
$c->setParameter('greeting', 'hi %name%');
$c->setParameter('message', '%greeting%!');
$c->compile();
echo $c->getParameter('message');
``` | «hi bob» Пояснение: 参数引用会在编译时递归解析,最终输出 'hi Bob'。
Raw{"answer": "hi Bob", "解释": "参数引用会在编译时递归解析,最终输出 'hi Bob'。"} | неверно верный: «hi bob!» | compile() 传递性地解析 % 引用:%greeting% → 'hi %name%' → 'hi Bob!',答案需要两步拼接。 |
T24-L9 0.52 c | Bootstrap | 在 Bootstrap 5.3 中,视口宽度 992px 时 .container 的 max-width 是多少? | «960px» Пояснение: Bootstrap 5.3 中,.container 在视口宽度为 992px 时,其 max-width 为 960px,这是为 lg 断点(≥992px)定义的默认值。
Raw{"answer": "960px", "解释": "Bootstrap 5.3 中,.container 在视口宽度为 992px 时,其 max-width 为 960px,这是为 lg 断点(≥992px)定义的默认值。"} | верно | 5.x 的 container 宽度:540/720/960/1140/1320(sm–xxl);992 → 960px。 |
T24-L10 0.4 c | Bootstrap | 在 Bootstrap 5.3 中,`<p class="text-danger text-primary">…</p>` 的文字颜色由哪个工具类决定?回答胜出的类名。 | «text-primary» Пояснение: text-primary 和 text-danger 都设置 color,text-primary 在文档中更靠后,因此胜出。
Raw{"answer": "text-primary", "解释": "text-primary 和 text-danger 都设置 color,text-primary 在文档中更靠后,因此胜出。"} | неверно верный: «text-danger» | 特异性相同——后声明的规则获胜:text-danger 在 text-primary 之后声明。 |
T25-L9 0.36 c | 整洁架构 | 层:Domain、Application、Infrastructure。deptrac 规则:Application → Domain;Infrastructure → Domain、Application;Domain → 仅 Domain。
对于这个类,deptrac 会报告多少个违规(Violations)?
```php
namespace App\Domain;
use App\Application\PlaceOrder;
use App\Infrastructure\Db;
class OrderService
{
public function __construct(
private PlaceOrder $handler,
private Db $db,
) {}
}
``` | «2» Пояснение: Domain 层引入了 Application 和 Infrastructure 层的依赖,违反了 Domain 仅依赖 Domain 的规则。
Raw{"answer": 2, "解释": "Domain 层引入了 Application 和 Infrastructure 层的依赖,违反了 Domain 仅依赖 Domain 的规则。"} | верно | Domain 只能依赖 Domain:PlaceOrder(Application)+ Db(Infrastructure)= 2。 |
T25-L10 0.54 c | 整洁架构 | 层:Domain、Application、Infrastructure。deptrac 规则:Application → Domain;Infrastructure → Domain、Application;Domain → 仅 Domain。
对于这个类,deptrac 会报告多少个违规(Violations)?
```php
namespace App\Domain;
use App\Application\PlaceOrder;
use App\Infrastructure\Db;
class BillingService
{
public function __construct(
private PlaceOrder $handler,
private Db $db,
private \App\Infrastructure\Logger $logger,
) {}
}
``` | «3» Пояснение: 该 Domain 类引用了 Application 层(PlaceOrder)和 Infrastructure 层(Db, Logger)的三个符号,违反了「Domain 仅可依赖 Domain」的规则,因此产生 3 个违规。
Raw```json ⏎ { ⏎ "answer": 3, ⏎ "解释": "该 Domain 类引用了 Application 层(PlaceOrder)和 Infrastructure 层(Db, Logger)的三个符号,违反了「Domain 仅可依赖 Domain」的规则,因此产生 3 个违规。" ⏎ } ⏎ ``` | верно | 内联 FQCN \App\Infrastructure\Logger 也计入:Application + Db + Logger = 3。 |
T26-L10 0.4 c | DDD | 这段代码会输出什么?
```php
final class Money
{
public function __construct(public readonly int $amount) {}
public function add(Money $o): Money
{
return new self($this->amount + $o->amount);
}
}
$a = new Money(10);
$c = $a->add(new Money(5));
echo $a->amount . ',' . $c->amount;
``` | «10,15» Пояснение: 对象不可变,原对象未改变,新对象金额为相加值
Raw{"answer": "10,15", "解释": "对象不可变,原对象未改变,新对象金额为相加值"} | верно | 值对象不可变:add() 返回新实例,原对象不变。 |
T26-L9 0.46 c | DDD | 这段代码会输出什么?
```php
final class Order
{
private array $items = [];
public function add(string $sku): void
{
$this->items[$sku] = true;
}
public function count(): int
{
return count($this->items);
}
public function remove(string $sku): void
{
if (count($this->items) === 1) {
throw new DomainException('last item');
}
unset($this->items[$sku]);
}
}
$o = new Order;
$o->add('a');
try {
$o->remove('a');
} catch (DomainException) {
}
echo $o->count();
``` | «1» Пояснение: 添加了一项,当尝试移除该项时因为它是最后一项而抛出异常,所以项数仍为 1。
Raw{"answer": 1, "解释": "添加了一项,当尝试移除该项时因为它是最后一项而抛出异常,所以项数仍为 1。"} | верно | 失败的 remove 不改变聚合状态:不变量在 unset 之前抛出——count 仍为 1。 |
VC-L9 3.36 c | PHP 8.4–8.5 | 这段代码在 PHP 8.5 上会输出什么?
```php
class C
{
public function hi(): string { return 'hi'; }
}
echo new C()->hi();
``` | «hi» Пояснение: 代码调用C类的hi()方法,该方法返回字符串'hi',因此输出为'hi'。
Raw```json ⏎ { ⏎ "answer": "hi", ⏎ "解释": "代码调用C类的hi()方法,该方法返回字符串'hi',因此输出为'hi'。" ⏎ } ⏎ ``` | верно | 自 8.4 起,方法链中的 new 无需外层括号。 |
VC-L10 3.41 c | PHP 8.4–8.5 | 这段代码在 PHP 8.5 上会输出什么?
```php
class Heavy
{
public int $v = 0;
}
$r = new ReflectionClass(Heavy::class);
$o = $r->newLazyGhost(function (Heavy $obj) {
$obj->v = 21;
});
echo $r->isUninitializedLazyObject($o) ? 'yes' : 'no';
$o->v;
echo $r->isUninitializedLazyObject($o) ? 'yes' : 'no';
``` | «yesno» Пояснение: 调用 newLazyGhost 创建的对象在首次属性访问前,isUninitializedLazyObject 返回 true;访问 $obj->v 触发初始化后,返回 false。
Raw```json ⏎ { ⏎ "answer": "yesno", ⏎ "解释": "调用 newLazyGhost 创建的对象在首次属性访问前,isUninitializedLazyObject 返回 true;访问 $obj->v 触发初始化后,返回 false。" ⏎ } ⏎ ``` | верно | newLazyGhost(8.4):对象在首次访问前保持惰性——读取属性会触发初始化并清除标志。 |
T28-L9 0.34 c | Symfony:版本 | 项目从 Symfony 6.4 升级到 8.1。这段代码在 8.1 上会输出什么?
```php
echo class_exists(\Symfony\Component\Security\Guard\AbstractGuardAuthenticator::class)
? 'yes' : 'no';
``` | «no» Пояснение: 在 Symfony 8 中,Security Guard 组件被移除。
Raw```json ⏎ {"answer": "no", "解释": "在 Symfony 8 中,Security Guard 组件被移除。"} ⏎ ``` | верно | Guard 认证在 Symfony 7.0 中被移除——8.1 中已无此类。 |
T28-L10 0.33 c | Symfony:版本 | 项目从 Symfony 6.4 升级到 8.1。这段代码在 8.1 上会输出什么?
```php
echo class_exists(\Symfony\Component\Routing\Loader\AnnotationClassLoader::class)
? 'yes' : 'no';
echo class_exists(\Symfony\Component\Routing\Loader\AttributeClassLoader::class)
? 'yes' : 'no';
``` | «noyes» Пояснение: Symfony 8.0 移除了基于注解(Annotation)的类加载器,而保留了基于属性(Attribute)的类加载器。
Raw{"answer": "noyes", "解释": "Symfony 8.0 移除了基于注解(Annotation)的类加载器,而保留了基于属性(Attribute)的类加载器。"} | верно | 注解加载器在 7.0 中被移除,只保留了属性加载器(Annotation→Attribute)。 |