Итоги Heisenbug 2025 Autumn:
🟠 🟠 🟠 QA превращается в R&D-дисциплину
🟠 🟠 🟠 Тестирование становится данными, кодом и частью pipeline-а
🟠 🟠 🟠 В фокусе - автоматизация через AI и сценарное мышление
🟠 🟠 🟠 Новая реальность рынка занятости: адаптация к еще более узкой воронке требований
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаем разговор об исключениях
throw и try-catchPlease open Telegram to view this post
VIEW IN TELEGRAM
throwПомимо использования стандартных библиотек для генерирования исключений, мы также можем самостоятельно создавать исключения явным образом, используя оператор
throw. Рассмотрим обработку исключения на примере класса
NoSuchElementException
fun filterPets(petList: List<GetPetResponse>, petId: Long): GetPetResponse {
return petList.find {
it.id == petId
} ?: throw NoSuchElementException("Питомец с $petId отсутствует")
}
petId в списке petList исполнение функции будет прервано на исключение NoSuchElementException("Питомец с $petId отсутствует”)try-catch обертки
fun filterPets(petList: List<GetPetResponse>, petId: Long): GetPetResponse? {
return try {
petList.find {
it.id == petId
} ?: throw NoSuchElementException("Питомец с $petId отсутствует")
} catch (e: Exception) {
println("Неожиданная ошибка при поиске питомца: ${e.message}")
null
}
}
try-catch повсеместно, тк за ними могут скрываться более серьезные ошибки.Please open Telegram to view this post
VIEW IN TELEGRAM
ОПИСАНИЕ:
Вам даны два массива целых чисел nums1 и nums2, отсортированные в порядке убывания, и два целых числа m и n, представляющие количество элементов в nums1 и nums2 соответственно.
Объедините nums1 и nums2 в один массив, отсортированный в порядке убывания.
Конечный отсортированный массив не должен возвращаться функцией, а должен храниться внутри массива nums1. Для этого nums1 имеет длину m + n, где первые m элементов обозначают элементы, которые должны быть объединены, а последние n элементов установлены в 0 и должны быть проигнорированы. nums2 имеет длину n.
ПРИМЕРЫ
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Explanation: The arrays we are merging are [1,2,3] and [2,5,6].
The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.
Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
Explanation: The arrays we are merging are [1] and [].
The result of the merge is [1].
Input: nums1 = [0], m = 0, nums2 = [1], n = 1
Output: [1]
Explanation: The arrays we are merging are [] and [1].
The result of the merge is [1].
Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.
Please open Telegram to view this post
VIEW IN TELEGRAM
LeetCode
Merge Sorted Array - LeetCode
Can you solve this real interview question? Merge Sorted Array - You are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively.
Merge nums1…
Merge nums1…
В прошлом месяце OpenAI📱 представили свою новую разработку - браузер со встроенным AI - ChatGPT Atlas.
Больше не требуется копировать-вставлять информацию из одного места в другое для последующего анализа - теперь можно получить обработанные данные “на месте”.
Давайте посмотрим, что же заявлено в анонсе.
Больше не требуется копировать-вставлять информацию из одного места в другое для последующего анализа - теперь можно получить обработанные данные “на месте”.
Давайте посмотрим, что же заявлено в анонсе.
Please open Telegram to view this post
VIEW IN TELEGRAM
OpenAI
Introducing ChatGPT Atlas
This post introduced ChatGPT Atlas, a browser with ChatGPT built in. Atlas has since been deprecated.
В первом приближении реализовано несколько функциональностей:
🔺
Здесь ничего революционно нового: умный поиск. Такое уже умеют браузеры-конкуренты, однако любопытно посмотреть, как с аналогичными задачами будет справляться помощник с более широким персонализированным контекстом “под капотом”.
Вижу здесь риск только в моменте самоограничения выдачи рамками уже имеющегося индивидуального контекста, собранного из весов (доводов) модели о пользователе.
Open a tabНовая вкладка — это ваша отправная точка в Atlas. Задайте вопрос или введите URL-адрес, чтобы увидеть более быстрые и полезные результаты в одном месте.
Здесь ничего революционно нового: умный поиск. Такое уже умеют браузеры-конкуренты, однако любопытно посмотреть, как с аналогичными задачами будет справляться помощник с более широким персонализированным контекстом “под капотом”.
Вижу здесь риск только в моменте самоограничения выдачи рамками уже имеющегося индивидуального контекста, собранного из весов (доводов) модели о пользователе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Ask ChatGPTНажмите «Спросить ChatGPT», чтобы открыть боковую панель ChatGPT на любой странице и обобщить, объяснить или выполнить задачи прямо в вашем окне. ChatGPT может видеть детали страницы, на которой вы находитесь, поэтому ответы более полезны и всегда имеют правильный контекст.
Одно из основных отличий от конкурентов ПОКА - возможность получения комментариев по всему материалу страницы “на месте”.
Больше не нужно копировать-вставлять информацию в отдельный чат целиком для “обучения” модели контексту. Теперь, обрабатывая входной запрос, модель уже будет иметь все необходимые предварительные данные.
Основную пользу в текущей области знаний вижу в возможности анализа и составления базового тест-сьюта проверок для выделенного фрагмента бизнес- или системных требований. А так же для проверки возможностей ревью веб мр-ов «из коробки» с вопросом, будет ли в таком случае у модели иметься доступ к данным всего проекта.
То есть будет ли возможность схлопнуть так же потребности в использовании сторонних помощников для анализа и и ревью кода от самих сервисов по типу
github.Please open Telegram to view this post
VIEW IN TELEGRAM
Use cursorChatGPT также может помочь вам при написании текста в любом открытом текстовом поле, предлагая встроенные правки и предложения.
То же избавление пользователей от лишних телодвижений - возможность внесения правок в любые текстовые поля “на месте”.
Если не касаться примитичной рутины, то, прикрепив к чату/каналу/письму, к примеру, файл с описанием требований к тому или иному функционалу, можно получить развернутое представление о работе такого функционала для массового или точечного информирования. Удобно для коммуникация с коллегами из смежных продуктов, команд.
Туда же правки по ревью, сценариям и пр.
Please open Telegram to view this post
VIEW IN TELEGRAM
Personalized suggestionsChatGPT может запоминать, что вы изучали, и предлагать, что делать дальше: вернуться к предыдущим страницам, углубиться в тему, найти связанные идеи или автоматизировать рутинные задачи.
В целом, многие браузеры уже предлагают возможности персонализации, однако любопытно посмотреть, как подобного рода рекомендации будут работать с данными, предоставленными на основании не только пользовательских сессий, но и всех данных, имеющихся у модели
И поскольку область - смежная с умным поиском, то и риски подразумеваются те же.
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Наибольший интерес вызывает новый
Что это такое:
Браузеры-конкуренты достаточно давно научились встраивать аналогичных агентов-помощников прямо в результаты выдачи, когда, помимо ссылок под запросом, можно получить сагрегированную обощенную выжимку под введенные данные.
Что же сделали в📱 :
Компания не стала двигаться в сторону продажи своих решений сторонним браузерам, как это делается с LLM-моделями в средах разработки, а предложила принципиально новый подход, где агент руководит браузером, подменяя собой действия пользователя, а не наоборот.
Зачатки такого подхода можно было наблюдать в
Что же касается профессиональной зоны интересов, то можно отметить, что пока еще в Atlas отсуствуют инструменты разработчика для работы с веб-проектами.
🔼 Таким образом, Atlas лишает пользователя необходимости сталкиваться с выбором, анализировать и сравнивать работу сразу нескольких различных моделей обработки данных, а так же уменьшает количество “ручного” труда по наполнению контекстом.
🔽 Однако важно понимать, что такое слияние так или иначе ограничивает “кругозор” получаемой информации, поскольку, как и в случае с любыми автогенераторами, персонализация может сузить вариативность.
➡️ Не забываем, что любой агент - прототип пользователя. Со временем он обучается. То есть любое заданное “дано” будет вероятнее всего выполнено в том стиле и с тем knowledge base, которые были заданы в ходе “общения” модели с юзером. Что тоже может быть как плюсом, так и минусом.
Agent Mode уже внутри ChatGPT Atlas. Что это такое:
Браузеры-конкуренты достаточно давно научились встраивать аналогичных агентов-помощников прямо в результаты выдачи, когда, помимо ссылок под запросом, можно получить сагрегированную обощенную выжимку под введенные данные.
Что же сделали в
OpenAI Компания не стала двигаться в сторону продажи своих решений сторонним браузерам, как это делается с LLM-моделями в средах разработки, а предложила принципиально новый подход, где агент руководит браузером, подменяя собой действия пользователя, а не наоборот.
Зачатки такого подхода можно было наблюдать в
workflow automation системах по типу n8n.io, где самостоятельно построив архитектуру, пользователь может автоматически управлять сразу несколькими инструментами по одному запросу. Однако OpenAI предлагает еще более автоматизированный инструмент, в котором архитектура строится вне глаз конечного потребителя, что может быть одновременно и хорошо и плохо. Что же касается профессиональной зоны интересов, то можно отметить, что пока еще в Atlas отсуствуют инструменты разработчика для работы с веб-проектами.
Please open Telegram to view this post
VIEW IN TELEGRAM
qa.log
Зачем такая задача?
🔽 Задача показывает, как объединять данные без выделения дополнительной памяти.
Мы не создаем новый список, а аккуратно заполняем уже существующий, упорядочивая элементы “на лету”.
К примеру, у нас уже есть какие-то данные по каким-то товарам и мы хотим подключить “нового” поставщика; Или хотим отображать результат слияния нескольких товарных категорий или рекомендательных единиц в одном списке быстро и дешево.
Мы не создаем новый список, а аккуратно заполняем уже существующий, упорядочивая элементы “на лету”.
К примеру, у нас уже есть какие-то данные по каким-то товарам и мы хотим подключить “нового” поставщика; Или хотим отображать результат слияния нескольких товарных категорий или рекомендательных единиц в одном списке быстро и дешево.
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаем разговор об исключениях
Please open Telegram to view this post
VIEW IN TELEGRAM
qa.log
Ассерты
🔼 Если условие не выполняется, тест считается неуспешным, и фреймворк (например, JUnit) выбрасывает
Это часть соглашения фреймворков тестирования (например, JUnit, TestNG):
- они распознают
- и корректно отображают его в отчётах: с сообщением, строкой кода, и разницей между
Виды ассертов:
🟢
🟢
🟢
🟢
🟢
Assertions - это утверждения, которые проверяют, что определённое условие выполняется:
assertEquals(200, response.statusCode)
AssertionError.AssertionError — это потомок класса Error, а не Exception, и он не должен обрабатываться приложением. То есть в случае NullPointerException, например, приложение выплюнет исключение вне зависимости от того, обработает ли его разработчик. Это часть соглашения фреймворков тестирования (например, JUnit, TestNG):
- они распознают
AssertionError как падение теста;- и корректно отображают его в отчётах: с сообщением, строкой кода, и разницей между
expected/actual.Виды ассертов:
assertEquals = утвердить идентичность
fun <T> assertEquals(expected: T, actual: T, message: String? = null) {
if (expected != actual) {
val errorMsg = message ?: "Assertion failed: expected <$expected>, but was <$actual>"
throw AssertionError(errorMsg)
}
}
// Применение
val expectedStatus = 200
val actualStatus = apiResponse.statusCode
assertEquals(expectedStatus, actualStatus, "Некорректный статус ответа")
assertTrue = утвердить истинность
fun assertTrue(condition: Boolean, message: String? = null) {
if (!condition) {
throw AssertionError(message ?: "Assertion failed: expected true, but was false")
}
}
// Применение:
val petCreated = apiResponse.statusCode == 200
assertTrue(petCreated, "Питомец не был создан")
assertFalse = утвердить ложность
fun assertFalse(condition: Boolean, message: String? = null) {
if (condition) {
throw AssertionError(message ?: "Assertion failed: expected false, but was true")
}
}
// Использование:
val isError = apiResponse.statusCode >= 400
assertFalse(isError, "Ответ содержит ошибку: ${apiResponse.statusCode}")
assertNotNull = утвердить наличие
fun assertNotNull(value: Any?, message: String? = null) {
if (value == null) {
throw AssertionError(message ?: "Assertion failed: value was null")
}
}
// Использование:
val createdPetId = apiResponse.data?.id
assertNotNull(createdPetId, "ID созданного питомца не должен быть null")
assertNull = утвердить отсутствие
fun assertNull(value: Any?, message: String? = null) {
if (value != null) {
throw AssertionError(message ?: "Assertion failed: expected null, but was $value")
}
}
// Использование:
val deletedPet = apiClient.getPetById(999)
assertNull(deletedPet, "Удалённый питомец должен быть null")
Please open Telegram to view this post
VIEW IN TELEGRAM
Forbes: Крупные IT-компании обяжут поддерживать вузы для сохранения аккредитации
Наличие аккредитации позволят IT-компаниям “экономить” на налоговых отчислениях, что в свою очередь оставляет в бюджете неутилизированное пространство для занятости выгодоприобретателей-коммерсантов.
Для сохранения льготы предлагается принять участие в “поддержке образовательного сектора” по IT-специальностям путем организации стажировок, а так же проведения занятий в вузах для учащихся.
Ситуация win-win:
🔼 Для государства - прикладная актуализация образовательной базы по критически важному направлению и оптимизация расходов бюджета;
🔼 Для компаний - возможность сохранения налоговых льгот и, как следствие, большого процента бюджета, даже с учетом оплат стажировок и преподавания/менторства сотрудниками;
🔼 Для рядовых сотрудников компании - шанс на реализацию в сфере преподавания и некоторая прибавка к доходу.
Стажерские вакансии на всех площадках найма через 3..2..1..
Наличие аккредитации позволят IT-компаниям “экономить” на налоговых отчислениях, что в свою очередь оставляет в бюджете неутилизированное пространство для занятости выгодоприобретателей-коммерсантов.
Для сохранения льготы предлагается принять участие в “поддержке образовательного сектора” по IT-специальностям путем организации стажировок, а так же проведения занятий в вузах для учащихся.
Ситуация win-win:
Стажерские вакансии на всех площадках найма через 3..2..1..
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Кроме прочего, AI-ассистентом так же предлагается функциональность по поиску потенциальных проблем сверх требований. Удобно в качестве дополнительного фильтра для самопроверки.
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Теперь можно вызывать действия прямо из окна автодополнения.
Вводим одинарную (.), чтобы увидеть предложения по автодополнению кода, и двойную (..), чтобы отфильтровать результаты только по действиям.
Отсматриваем предварительный результат и применяем при его эффективности.
Такое дополнение позволяет редактировать наработки из одного места.
Полный список обновлений - What’s New in IntelliJ IDEA 2025.3
Please open Telegram to view this post
VIEW IN TELEGRAM
Разомнемся после праздников
🖥 Новая задача Best Time to Buy and Sell Stock
ОПИСАНИЕ:
ПРИМЕРЫ🔽 :
ОПИСАНИЕ:
Вам дан массив цен, где prices[i] — цена данной акции в i-й день.
Вы хотите максимизировать свою прибыль, выбрав один день для покупки одной акции и другой день в будущем для ее продажи.
Верните максимальную прибыль, которую вы можете получить от этой сделки. Если вы не можете получить никакой прибыли, верните 0.
ПРИМЕРЫ
Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.
Please open Telegram to view this post
VIEW IN TELEGRAM
LeetCode
Best Time to Buy and Sell Stock - LeetCode
Can you solve this real interview question? Best Time to Buy and Sell Stock - You are given an array prices where prices[i] is the price of a given stock on the ith day.
You want to maximize your profit by choosing a single day to buy one stock and choosing…
You want to maximize your profit by choosing a single day to buy one stock and choosing…
Продолжаем разговор об исключениях
Please open Telegram to view this post
VIEW IN TELEGRAM
qa.log
Кастомные ассерты
Создадим вспомогательный класс, в котором опишем интересующие нас проверки с использованием
Добавляем компаньона, который приводит тип получаемых данных к типу класса:
Проверяем полученный ответ и возвращаем значение в нужном типе:
🔽 Для стандартных проверок составление кастомных ассертов не требуется, так как большинство необходимых методов уже имеется в общедоступных библиотеках.
🔼 Однако иногда появляются точечно случаи, под которые таких проверок нет.
Custom Assert - ассерты, позволяющие выполнять проверки на своих условиях в дополнение к возможностям стандартной библиотеки.
ResponseAssert.assertThat(response)
.hasStatusCode200()
Создадим вспомогательный класс, в котором опишем интересующие нас проверки с использованием
AbstractAssert (из библиотеки assertj) типа данных самого класса и принимаемого значения:
class ResponseAssert(
actual: Response
) : AbstractAssert<ResponseAssert, Response>(
actual, ResponseAssert::class.java) {}
Добавляем компаньона, который приводит тип получаемых данных к типу класса:
companion object {
fun assertThat(actual: Response): ResponseAssert {
return ResponseAssert(actual)
}
}
Проверяем полученный ответ и возвращаем значение в нужном типе:
fun hasStatusCode200(): ResponseAssert {
if (actual.status() != 200) {
failWithMessage("Expected status code 200 but was ${actual.status()}")
}
return this
}
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Помимо генераций, AI-ассистентами так же предлагается функционал по объяснению фрагментов кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Использовать Codex возможно с подпиской JetBrains AI и своей учетной записью ChatGPT (или ключом API OpenAI). Никаких дополнительных приседаний - доступ прямо из чата AI-ассистента.
Представлены 3 режима работы:
• ридонли
• рв
• фул аксес (полностью автономный помощник с допуском к редактированию внешних файлов)
Дополнительно доступны последние версии моделей от OpenAI, а так же несколько опций глубины “мышления”:
• низкий
• средний
• высокий
• ультравысокий
Если подписки нет, то доступна пробная беслпатная версия на ограниченный срок, пока не будут исчерпаны промо-кредиты.
JetBrains так же сохранил для своих пользователей возможности мультимодельной работы: список доступных достаточно часто обновляемых LLM от других “поставщиков” размещается на своем прежнем месте - так же в окне чата с асситентом.
Что это меняет?
Небольшой демо-прокат по возможностям кодекса показал доступность к сразу несольким уровням настройки проектов, гибкость в предложении вариантов, более глубокое понимание витиеватого и в то же время абстрактного запроса, ну, и самое интересное - возможность сравнения с инструментами конкурентов!
Please open Telegram to view this post
VIEW IN TELEGRAM