💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. Читайте код построчно, учитывайте типы, атрибуты, пропуски и допущения анализа. После завершения откроются общий процент, 6 тематических шкал и объяснение к каждому заданию.
Вопрос 5 из 30
Ситуация: Цикл добавляет миллион значений в растущий вектор, и время увеличивается быстрее объёма данных. Какое заключение останется верным и на новых данных?
R Фрагмент R Копировать
n <- 10000
result <- numeric(n)
for (i in seq_len(n)) result[i] <- i^2
result[1:3]
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе; при этом главный риск состоит в том, что многократное расширение вектора через c() внутри цикла копирует данные и создаёт квадратичную стоимость
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что многократное расширение вектора через c() внутри цикла копирует данные и создаёт квадратичную стоимость
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место; при этом главный риск состоит в том, что один microbenchmark маленькой функции игнорирует ввод-вывод, создание данных и сборку мусора всего процесса
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе; следовательно, предупреждения можно не учитывать, если итог выглядит ожидаемо
Вопрос 6 из 30
Ситуация: Команда ускорила арифметику на наносекунды, но отчёт по-прежнему ждёт чтение гигабайтного файла. Какой принцип непосредственно относится к этому коду?
R Фрагмент R Копировать
tmp <- tempfile(); write.csv(mtcars,tmp,row.names=FALSE)
Rprof(); result <- read.csv(tmp); Rprof(NULL)
result <- summaryRprof()$by.total[1:3,]
result
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers
Вопрос 10 из 30
Ситуация: Команда ускорила арифметику на наносекунды, но отчёт по-прежнему ждёт чтение гигабайтного файла. Какой итог разбора не смешивает правило языка с впечатлением от результата?
R Фрагмент R Копировать
tmp <- tempfile(); write.csv(mtcars,tmp,row.names=FALSE)
Rprof(); result <- read.csv(tmp); Rprof(NULL)
result <- summaryRprof()$by.total[1:3,]
result
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что один microbenchmark маленькой функции игнорирует ввод-вывод, создание данных и сборку мусора всего процесса
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место; поэтому внешний вид напечатанного объекта важнее происхождения и структуры данных
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место; при этом главный риск состоит в том, что один microbenchmark маленькой функции игнорирует ввод-вывод, создание данных и сборку мусора всего процесса
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе; при этом главный риск состоит в том, что многократное расширение вектора через c() внутри цикла копирует данные и создаёт квадратичную стоимость
Вопрос 15 из 30
Ситуация: Функция должна вернуть расширенную копию таблицы, но добавляет столбец и в объект вызывающего кода. Как сформулировать вывод без лишних обобщений?
R Фрагмент R Копировать
library(data.table)
dt1 <- data.table(x=1:3)
dt2 <- dt1
dt2[, y := x*2]
result <- dt1
result
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что неожиданная мутация исходного объекта происходит, когда две переменные ссылаются на одну data.table
data.table изменяет данные по ссылке через := и использует ключи и индексы для быстрых операций без лишних копий; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
data.table изменяет данные по ссылке через := и использует ключи и индексы для быстрых операций без лишних копий; при этом главный риск состоит в том, что неожиданная мутация исходного объекта происходит, когда две переменные ссылаются на одну data.table
data.table изменяет данные по ссылке через := и использует ключи и индексы для быстрых операций без лишних копий; поэтому отсутствие сообщения об ошибке уже подтверждает корректность результата
Векторизованные операции переносят цикл в оптимизированный код и часто уменьшают накладные расходы интерпретатора, но не меняют асимптотику сами по себе; при этом главный риск состоит в том, что многократное расширение вектора через c() внутри цикла копирует данные и создаёт квадратичную стоимость
Вопрос 20 из 30
Ситуация: Четыре микроскопические задачи запускают на десятках процессов, и большая часть времени уходит на создание workers. Какое заключение лучше всего выдерживает проверку?
R Фрагмент R Копировать
library(parallel)
cl <- makeCluster(2)
result <- parLapply(cl, 1:4, function(i) sum((1:1e5)^i))
stopCluster(cl)
result
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место; при этом главный риск состоит в том, что один microbenchmark маленькой функции игнорирует ввод-вывод, создание данных и сборку мусора всего процесса
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; поэтому достаточно один раз проверить класс объекта на текущем наборе данных
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что set.seed перед форком не всегда даёт желаемые независимые последовательности во всех платформах и backend
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
Вопрос 21 из 30
Ситуация: После векторизации итог немного отличается, а downstream-порог превращает малую разницу в другую категорию. На какое свойство R здесь следует опереться?
R Фрагмент R Копировать
x <- runif(1000)
a <- sum(x)
b <- Reduce(`+`, x)
result <- all.equal(a,b,tolerance=1e-12)
result
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов
data.table изменяет данные по ссылке через := и использует ключи и индексы для быстрых операций без лишних копий
Профилирование измеряет, где программа действительно тратит время и память; оптимизация по впечатлению часто выбирает не то место
Вопрос 25 из 30
Ситуация: После векторизации итог немного отличается, а downstream-порог превращает малую разницу в другую категорию. Какой вывод точнее всего связывает механизм и главный риск?
R Фрагмент R Копировать
x <- runif(1000)
a <- sum(x)
b <- Reduce(`+`, x)
result <- all.equal(a,b,tolerance=1e-12)
result
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что быстрая версия меняет тип, округление или порядок строк и остаётся незамеченной по одной общей метрике времени
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers; при этом главный риск состоит в том, что set.seed перед форком не всегда даёт желаемые независимые последовательности во всех платформах и backend
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений; следовательно, совпадение числа строк можно считать полной проверкой решения
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений; при этом главный риск состоит в том, что быстрая версия меняет тип, округление или порядок строк и остаётся незамеченной по одной общей метрике времени
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping
Вопрос 30 из 30
Ситуация: Параллельные симуляции на Windows и Linux дают разные ответы, хотя установлен один seed. Что стоит написать в технической рецензии к этому фрагменту?
R Фрагмент R Копировать
RNGkind("L'Ecuyer-CMRG")
set.seed(14)
result <- .Random.seed[1:6]
result
Оптимизация должна сохранять численную корректность, порядок результатов, обработку ошибок и воспроизводимость случайных вычислений; при этом главный риск состоит в том, что быстрая версия меняет тип, округление или порядок строк и остаётся незамеченной по одной общей метрике времени
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers; поэтому повторный запуск в той же сессии заменяет проверку граничных случаев
Параллельное выполнение полезно только когда работа превышает стоимость запуска процессов, передачи данных и объединения результатов; при этом главный риск состоит в том, что set.seed перед форком не всегда даёт желаемые независимые последовательности во всех платформах и backend
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers; при этом главный риск состоит в том, что set.seed перед форком не всегда даёт желаемые независимые последовательности во всех платформах и backend
Параллельные случайные вычисления требуют независимых воспроизводимых потоков, например L'Ecuyer-CMRG, и сохранённой конфигурации workers; при этом главный риск состоит в том, что экспорт огромного объекта каждому worker умножает память и может сделать параллельную версию медленнее или вызвать swapping