💡 Инструкция: Выберите один ответ из пяти. На работу отведено 85 минут. После завершения откроются правильные ответы, объяснения и результаты по темам.
Вопрос 6 из 30
Какое утверждение точнее всего объясняет участок с `return sum(@view x[r])`?
V=\operatorname{view}(A,I)
Julia Julia · Представления без копирования (views) Копировать
function window_sum_copy(x, r)
return sum(x[r])
end
function window_sum_view(x, r)
return sum(@view x[r])
end
x = rand(1_000_000)
r = 100:200
@show window_sum_copy(x, r) window_sum_view(x, r)
`view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Вопрос 7 из 30
Какой контрольный тест лучше всего проверит правило, связанное с `return sum(@view x[r])`?
Julia Julia · Представления без копирования (views) Копировать
function window_sum_copy(x, r)
return sum(x[r])
end
function window_sum_view(x, r)
return sum(@view x[r])
end
x = rand(1_000_000)
r = 100:200
@show window_sum_copy(x, r) window_sum_view(x, r)
Проверить на отдельном примере, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Проверить на отдельном примере, что представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Проверить на отдельном примере, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Проверить на отдельном примере, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Проверить на отдельном примере, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Вопрос 9 из 30
При переносе кода с `return sum(@view x[r])` в библиотеку какой критерий нельзя заменять впечатлением «пример работает»?
V=\operatorname{view}(A,I)
Приёмка должна подтвердить, что представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Приёмка должна подтвердить, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Приёмка должна подтвердить, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Приёмка должна подтвердить, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Приёмка должна подтвердить, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Вопрос 11 из 30
Что именно следует из фрагмента с `axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())`?
M_{peak}\approx M_{buffer}+M_{state}
Julia Julia · Предвыделение Копировать
function axpy!(out, a, x, y)
axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())
@inbounds @simd for i in eachindex(out, x, y)
out[i] = a*x[i] + y[i]
end
return out
end
x = rand(1000); y = rand(1000); out = similar(x)
@show sum(axpy!(out, 2.0, x, y))
`@allocated` включает стоимость первой компиляции и потому лучше всего измеряет расход рабочего повторного вызова.
Предвыделение буфера и функции с `!` полезны в повторяющемся ядре, если владелец буфера ясен и размер проверяется до записи.
Предвыделенный буфер безопасно хранить глобально и переиспользовать из нескольких задач без владельца или синхронизации.
Представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Вопрос 12 из 30
Какую проверку стоит добавить для участка с `axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())`?
Julia Julia · Предвыделение Копировать
function axpy!(out, a, x, y)
axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())
@inbounds @simd for i in eachindex(out, x, y)
out[i] = a*x[i] + y[i]
end
return out
end
x = rand(1000); y = rand(1000); out = similar(x)
@show sum(axpy!(out, 2.0, x, y))
Проверить на отдельном примере, что сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Проверить на отдельном примере, что `@allocated` включает стоимость первой компиляции и потому лучше всего измеряет расход рабочего повторного вызова.
Проверить на отдельном примере, что представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Проверить на отдельном примере, что предвыделенный буфер безопасно хранить глобально и переиспользовать из нескольких задач без владельца или синхронизации.
Проверить на отдельном примере, что предвыделение буфера и функции с `!` полезны в повторяющемся ядре, если владелец буфера ясен и размер проверяется до записи.
Вопрос 13 из 30
Какой контракт следует закрепить при переработке строки `axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())`?
Julia Julia · Предвыделение Копировать
function axpy!(out, a, x, y)
axes(out) == axes(x) == axes(y) || throw(DimensionMismatch())
@inbounds @simd for i in eachindex(out, x, y)
out[i] = a*x[i] + y[i]
end
return out
end
x = rand(1000); y = rand(1000); out = similar(x)
@show sum(axpy!(out, 2.0, x, y))
Сохранить в реализации правило: Представление предпочтительнее копии и по времени, и по памяти; после вычисления оно не влияет на время жизни родительского массива.
Сохранить в реализации правило: Предвыделенный буфер безопасно хранить глобально и переиспользовать из нескольких задач без владельца или синхронизации.
Сохранить в реализации правило: Предвыделение буфера и функции с `!` полезны в повторяющемся ядре, если владелец буфера ясен и размер проверяется до записи.
Сохранить в реализации правило: `@allocated` включает стоимость первой компиляции и потому лучше всего измеряет расход рабочего повторного вызова.
Сохранить в реализации правило: Сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Вопрос 16 из 30
Какое объяснение для `length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))` выдержит проверку на другом допустимом входе?
reachable(o)\Rightarrow o\text{ не собирается}
Julia Julia · Жизненный цикл объектов Копировать
mutable struct Cache
data::Dict{Int,Vector{Float64}}
limit::Int
end
function insert!(c, key, value)
length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))
c.data[key] = value
end
cache = Cache(Dict(), 2)
`view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Вопрос 17 из 30
Какую проверку стоит добавить для участка с `length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))`?
Julia Julia · Жизненный цикл объектов Копировать
mutable struct Cache
data::Dict{Int,Vector{Float64}}
limit::Int
end
function insert!(c, key, value)
length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))
c.data[key] = value
end
cache = Cache(Dict(), 2)
Проверить на отдельном примере, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Проверить на отдельном примере, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Проверить на отдельном примере, что сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Проверить на отдельном примере, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Проверить на отдельном примере, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Вопрос 18 из 30
Что должно остаться истинным после рефакторинга участка с `length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))`?
Julia Julia · Жизненный цикл объектов Копировать
mutable struct Cache
data::Dict{Int,Vector{Float64}}
limit::Int
end
function insert!(c, key, value)
length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))
c.data[key] = value
end
cache = Cache(Dict(), 2)
Сохранить в реализации правило: `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Сохранить в реализации правило: Профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Сохранить в реализации правило: Архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Сохранить в реализации правило: Сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Сохранить в реализации правило: Сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Вопрос 19 из 30
Как проверить, что новая реализация `length(c.data) >= c.limit && delete!(c.data, first(keys(c.data)))` не изменила обещанное пользователю поведение?
reachable(o)\Rightarrow o\text{ не собирается}
Приёмка должна подтвердить, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Приёмка должна подтвердить, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Приёмка должна подтвердить, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Приёмка должна подтвердить, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Приёмка должна подтвердить, что сборщик мусора освобождает внешние дескрипторы в предсказуемый момент, поэтому явный `close` только дублирует работу.
Вопрос 22 из 30
Какой тест точнее всего зафиксирует границу поведения `out = Vector{Vector{Float64}}(undef, n)`?
Julia Julia · Профилирование решения Копировать
using Profile
function allocate_many(n)
out = Vector{Vector{Float64}}(undef, n)
for i in 1:n
out[i] = rand(i % 100 + 1)
end
return out
end
Profile.Allocs.clear(); Profile.Allocs.@profile sample_rate=1.0 allocate_many(1000)
@show length(Profile.Allocs.fetch().allocs)
Проверить на отдельном примере, что `@allocated` и `@btime` измеряют разные стороны расходов; результат интерпретируют после компиляции и с корректной интерполяцией входов.
Проверить на отдельном примере, что общее число выделенных байтов само указывает, какую функцию нужно переписать; стек аллокаций и профиль рабочей нагрузки не добавляют существенной информации.
Проверить на отдельном примере, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Проверить на отдельном примере, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Проверить на отдельном примере, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Вопрос 24 из 30
После обновления Julia или пакета поведение участка с `out = Vector{Vector{Float64}}(undef, n)` изменилось. Какой критерий приёмки остаётся корректным?
B=\sum_s B_s
Приёмка должна подтвердить, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Приёмка должна подтвердить, что общее число выделенных байтов само указывает, какую функцию нужно переписать; стек аллокаций и профиль рабочей нагрузки не добавляют существенной информации.
Приёмка должна подтвердить, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Приёмка должна подтвердить, что `@allocated` и `@btime` измеряют разные стороны расходов; результат интерпретируют после компиляции и с корректной интерполяцией входов.
Приёмка должна подтвердить, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Вопрос 27 из 30
Какой контрольный тест лучше всего проверит правило, связанное с `y = copy(x)`?
Julia Julia · Архитектурные компромиссы Копировать
function normalized_copy(x)
y = copy(x)
y ./= maximum(abs, y)
return y
end
function normalized!(x)
x ./= maximum(abs, x)
return x
end
x = rand(1000)
@show sum(normalized_copy(x)) sum(normalized!(copy(x)))
Проверить на отдельном примере, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Проверить на отдельном примере, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.
Проверить на отдельном примере, что устранение всех аллокаций важнее читаемости и ясного владения данными, потому что мутация и общий буфер не меняют архитектурный риск.
Проверить на отдельном примере, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Проверить на отдельном примере, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Вопрос 29 из 30
После обновления Julia или пакета поведение участка с `y = copy(x)` изменилось. Какой критерий приёмки остаётся корректным?
C=\alpha T+\beta M+\gamma R
Приёмка должна подтвердить, что устранение всех аллокаций важнее читаемости и ясного владения данными, потому что мутация и общий буфер не меняют архитектурный риск.
Приёмка должна подтвердить, что `view` уменьшает копирование срезов, но мелкое представление в коротком коде иногда дороже простой копии и может удерживать большой родительский массив.
Приёмка должна подтвердить, что профиль аллокаций должен указывать стек и объём на рабочей нагрузке; общее число байтов без места возникновения редко подсказывает исправление.
Приёмка должна подтвердить, что сборщик мусора освобождает недостижимые объекты, но внешние ресурсы и большие кэши требуют явного жизненного цикла; финализатор не заменяет штатное закрытие.
Приёмка должна подтвердить, что архитектурный компромисс учитывает простоту, задержку, память и риск ошибочной мутации; нулевая аллокация не всегда важнее ясного и проверяемого кода.