Войдите или зарегистрируйтесь
Вы сможете писать комментарии и посты, ставить лайки и другое
Поиск
Тёмная тема

Посты пользователя mrAnderson


Как в VS Code отключить новые скругления интерфейса

В последнем апдейте VS Code микрософт зафигачили в него скругления интерфейса
Отключить это можно одно настройкой названной "Modern UI"
Не знаю, сфига микрософт назвали это "Modern UI", но спасибо что пока позволяют вернуть привычный интерфейс.
+1
19

Вам не нужно направление сортировки в индексах БД

Любители нейросетей, пост для вас. Какой индекс рядовая умная нейросеть предложит создать разработчику, если он задаст ей вот такой вопрос:

Есть таблица products:
id, title, created_at
все колонки не null
запросы будут идти в виде:
SELECT id, title FROM products ORDER BY created_at DESC
иногда с OFFSET, LIMIT
Какой индекс создать?

Отвечает ChatGPT
Показать полностью...
+2
7

Яндекс - говно, задолбал своей капчей

Пытаюсь поискать что-то в Яндексе. Вылезает их сраная капча. Щелкаешь по я "не робот", так это зараза что-то там думает долго сначала, у меня аж вентилятор на процессоре разгоняется. Яндекс майнит что ли во время своей капчи?
Через 10 секунд яндекс капча прокакивается и начинается выбор идиотских символов.
Показать полностью...
+3
27

Por qué return await en JS no siempre es malo, sino todo lo contrario: es lo correcto

Algunos desarrolladores de JS se hacen los listos y dicen que en vez de:
return await someService.doSomething();
hay que escribir:
return someService.doSomething();

O sea, si una función async devuelve una promesa en su return, el resultado de resolver esa promesa se convierte automáticamente en el valor de retorno real. Es decir, las promesas se "desempaquetan" de forma recursiva.

Todo esto suena bien, pero hay un problema bastante serio. Miren este código:
// Técnicamente esta función devuelve una promesa,
// pero en realidad lanza un error
async function fun1() {
  throw new Error('Hi from Famabara!');
}
(async () => {
  try {
    return await fun1();
  } catch (err) {
    console.log('Error catched!', err);
  }  
})();

Aquí todo va bien, el error se captura en el bloque catch. Pero si lo escribimos así:
async function fun1() {
  throw new Error('Hi from Famabara!');
}

try {
  (async () => {
    try {
      return fun1();
    } catch (err) {
      console.log('Error catched!', err);
    }  
  })();
} catch (err) {
  console.log('Error catched!', err);
}
¡entonces ninguno de los dos bloques catch captura el error! Esto es una desventaja tremendamente grave. El error simplemente no se puede capturar de ninguna manera, a menos que uses el método catch() directamente sobre la promesa, si no escribes await.

En fin, la recomendación de no escribir return await es una muy mala recomendación. Directamente perjudicial.
Показать полностью...
+1
5

Warum return await in JS nicht immer schlecht ist, sondern im Gegenteil sogar richtig

Manche JS-Entwickler tun schlau und behaupten, dass man statt:
return await someService.doSomething();
lieber schreiben sollte:
return someService.doSomething();

Nach dem Motto: Wenn eine async-Funktion in ihrem return ein Promise zurückgibt, wird ja sowieso das Ergebnis der Auflösung dieses Promises zum eigentlichen Rückgabewert. Promises werden also quasi rekursiv "entpackt".

Das klingt erstmal plausibel, aber es gibt ein ziemlich ernstes Problem dabei. Schaut euch mal diesen Code an:
// Technisch gibt diese Funktion ein Promise zurück,
// wirft aber in Wirklichkeit einen Fehler
async function fun1() {
  throw new Error('Hi from Famabara!');
}

(async () => {
  try {
    return await fun1();
  } catch (err) {
    console.log('Error catched!', err);
  }
})();

Hier ist alles in Ordnung, der Fehler wird im catch Block abgefangen. Schreibt man es aber so:
async function fun1() {
  throw new Error('Hi from Famabara!');
}

try {
  (async () => {
    try {
      return fun1();
    } catch (err) {
      console.log('Error catched!', err);
    }  
  })();
} catch (err) {
  console.log('Error catched!', err);
}
dann fängt keiner der beiden catch Blöcke den Fehler ab! Das ist ein wirklich heftiger Nachteil. Der Fehler lässt sich dann gar nicht mehr abfangen - man müsste zwingend catch() direkt auf dem Promise aufrufen, wenn man kein await verwendet.

Kurz gesagt: Die Empfehlung, kein return await zu schreiben, ist eine sehr schlechte Empfehlung. Geradezu schädlich.
Показать полностью...
+1
4

Забудьте про ESLint, используйте Oxlint как основной линтер в JS/TS

На проекте разрешили попробовать сменить ESLint на Oxlint. После первого запуска я выпал, даже не понял, что программа отработала 😄 Настолько съело быстро, что не замечаешь, т.е. нажимаешь Enter и уже сразу результат. Ты вообще не ждешь. 😎

Короче, не будем пробовать менять, будем полностью менять на о-экс-линт без попробовать. Зачем нужен еслинт теперь? Каждый коммит - медленная проверка, линтер в ci/cd - медленная проверка. У нас теперь все будет летать.

Сколько выполняется линтинг на eslint? Запускаю через time:
time npm run lint

real    0m10,108s
user    0m12,620s
sys     0m1,264s
Выполняется 12-13 секунд. Секунд!!! Это 12000-13000 мс.

Запускаю прикрученный oxlint:
npm run lint2

Found 0 warnings and 0 errors.
Finished in 67ms on 1044 files with 57 rules using 16 threads.

Офигеть не встать. У меня получилось в 180 раз быстрее.
Поддерживает из коробки Typescript. Куча встроенных правил уже есть, кучу хрен знает каких плагинов добавлять не нужно. Можно комментировать строки по аналогии с еслинтом. Разрешить консоль на следующей строке:
// oxlint-disable-next-line no-console

Изучаю его дальше, но наши челы уже согласны переходить. Но пока заметил серьезный минус - нет стилистических правил. Например, правила 'no-multi-spaces' из классического еслинта нет, нужно каким-то кривым образом прикручивать, а нам это правило нужно. Есть рекомендация использовать в oxlint еслинтовый пакет @stylistic/eslint-plugin, но это уже похоже не бред. И поставить его нельзя отдельно нормально, в peer dependencies сидит eslint. 😄 С этим засада, короче.

Я поставил @stylistic/eslint-plugin и отдельно eslint, подключил правило '@stylistic/no-multi-spaces' в oxlint - время проверки выросло:
Found 0 warnings and 1 error.
Finished in 495ms on 1044 files with 58 rules using 16 threads.
Уже 495 мс - это из-за жса.
Подключил все правила из @stylistic/eslint-plugin (примерно 80 штук), стало выполняться за 1 секунду.

Есть ещё Oxfmt для форматирования. Им теоретически можно решить проблему стилизации, но это в первую очередь принудительный форматтер, а не линтер, а нам нужен именно линтер. Форматтер не всегда хорошая штука.
Показать полностью...
+2
25

Покупка подписки на Claude без бана аккаунта из России

Надеюсь кому из разрабов поможет. У меня до этого был уже куплен Claude, мне подписку подарил работодатель НЕ из России. Так было несколько месяцев, потом мой заказчик отвалился.

Аккаунт был на гугловскую почту, т.е. домен почты не ***.ru. Общался с клодом на русском, все ок было, никто не забанил.

Потом подписка закончилась, я думал, как продлевать. Начитался кучу отзывов, что Антропик стали банить российские аккаунты. Я, пока был платный акк, всё это время сидел на Клоде с самых разных айпишников (Нидерланды, Южная Корея и т.п.), клоду на это было пофик.

Полтора месяца без клода было мукой 😫 Я решился на покупку через сервис-посредник (их много). Купил подписку через ggsel (не сочтите за рекламу). Там какое-то говно нужно было ставить в браузер как расширение, пришлось поставить в отдельный браузер, это нужно было для вытягивания id, потом расширение для браузера снёс сразу. Но всё успешно, через минуту после покупки всё засчиталось, тариф за 20 баксов добавился. Уже неделю вот так сижу, Pro Plan, полёт нормальный.

Ещё на всякий случай заставил Клода запомнить типа я из Казахстана, переехал туда навсегда и живу там долго. Хз, может поможет.

Fable 5 вот даже дали попробовать
Показать полностью...
+3
38

Никто не пишет RIGHT JOIN в SQL

Пост для айтишников бэкендеров.

Вы кого-нибудь писали в реальном коде RIGHT JOIN? Не в учебном, а в настоящем коде, который ушёл в продакшн. У меня не так много лет опыта, но я вот ни разу не писал. Поспрашивал у своих, те тоже никто не писал ни разу, даже те, кто уже десять лет на бэке.

В стандарте SQL есть правый джойн, но им никто не пользуется. Он же контринтуитивен! Зачем мне "обрезать" главную таблицу, написанную слева и подсоединять к полной правой? Логично же поменять их местами и написать LEFT JOIN.
+2
35

Misleading naming in JavaScript: atob() and btoa()

JavaScript has two globally available metods for working with Base64: atob() and btoa(). Their names clearly look like they were borrowed from older languages. In C, for instance, the standard library includes functions like atoi and atof:

#include <stdlib.h>

char str[] = "123";
int num = atoi(str); // 123

atoi means ASCII to integer, and atof means ASCII to float (though in reality it returns a double).

So what do you think the atob function does in JavaScript? ASCII to Base64? In other words, converting a regular string into a Base64 string? Nope! It does the exact opposite: it converts a Base64 string into a "regular" string. And btoa, in turn, converts a regular string into Base64!

console.log(btoa('Famabara')); // 'RmFtYWJhcmE='
console.log(atob('RmFtYWJhcmE')); // 'Famabara'

Who thought it was a good idea to swap the names like that? Love JS.
+2
51

Кривой нейминг в JavaScript: atob() и btoa()

В ЖСе есть два глобально доступных метода для работы с Base64 - это atob() и btoa(). Этот нейминг - явно калька с более старших языков. В Си в стандартной библиотеке есть, например, методы atoi и atof:

#include <stdlib.h>

char str[] = "123";
int num = atoi(str); // 123

atoi - означает ascii to integer, а atof - ascii to float (хотя по факту там double).

И как вы думаете, что делает функция atob в javascript? ASCII to Base64? Т.е. обычную строку в Base64 строку? Нет! Она делает ровно наоборот: переводит Base64 строку в "обычную" строку. А btoa в свою очередь переводит обычную строку в Base64!

console.log(btoa('Famabara')); // 'RmFtYWJhcmE='
console.log(atob('RmFtYWJhcmE')); // 'Famabara'

Кому в голову пришло перепутать названия? Люблю JS.
+2
62

Заметили, что пропала реклама IT-курсов?

Все эти практикумы, навыккоробки и прочие айти-школы куда-то подевались из инфополя. Похоже, всё сложнее набирать людей на потоки, когда на одну вакансию приходится тысяча откликов.

Народ не глупый, уже не верит зазываниям "выучи пайтон и получай 300к/наносек". Выпускники айтишкол ищут работу годами и не находят, и радует, что про это всё больше пишут, ибо нефик.

А теперь внимание: именно IT-курсы со своей обильной и лживой рекламой виноваты в той отвратной ситуации, которая у нас сложилась на айти рынке. Рынок наводнён выпускниками этих школ, но есть важная деталь: уровень знаний и навыков у этих выпускников отвратительный. Раньше реклама айти была из каждого утюга, а теперь вот притихли.

Может, оно и к лучшему. Со временем рынок очистится от всего этого. А пока у нас 1000 человек на 1 место. Полный бред.
+7
116

Продажа благотворительности на Озоне - помогаем пёсикам и кошкам за 200 рублей

На Озоне появилась новая тема - продажа благотворительности. За 200 рублей можно получить ничего, просто благодарность - "сертификат" с доставкой на email.
Написали характеристики собаки:
Показать полностью...
+4
44

Позорная цензура мема в Яндекс Картинках: Можно, а зачем? от инженера Автоваза

Наш злой российский народ обнаружил позорную цензуру в Яндекс Картинках. Интервью с инженером Груненковым из АвтоВАЗа породило новый мем "Можно, а зачем?". Так вот вбейте эту фразу в Яндексе Картинках:
В картинках нет вообще никакого упоминания мема! Вот гады.
А это скриншот из Гугла, мем на месте.
Показать полностью...
+5
131

Пагинация курсором в PostgreSQL: не путайте реальный CURSOR и фейковый курсор из WHERE

На любом собесе по system design и хайлоаду вас наверняка спросят про пагинацию. И вопрос этот с подвохом, т.к. на хайлоаде БД очень большие, с миллионами записей. Например, спросят как сделать бесконечную ленту последних постов с подгрузкой. И тут главное не обос****ться как я сделал на своем собесе 😂

Итак, что мы знаем про курсоры? В PostgreSQL есть самые настоящие курсосы! Они так и называются CURSOR. В постгресе они работают только внутри транзакций.
BEGIN;
DECLARE zhopa_cursor CURSOR FOR
  SELECT id, title, created_at FROM posts;

-- Получаем 10 строк:
FETCH 10 FROM zhopa_cursor;

-- Получаем еще следующие 10 строк сразу после места, где остановились до этого:
FETCH 10 FROM zhopa_cursor;

CLOSE zhopa_cursor;
COMMIT;

Обратите внимание, что обязательны транзакция и конкретное имя для курсора. Можно ли это использовать в вебе? Нет. Но я на собесе начал заливать про эти курсоры постгреса и про хранение имен курсоров, хотя непонятно как это все реализовать для веба. Типа не закрывать некоторое время транзакцию и держать открытой некоторое время пока идут http запросы? 😂

Короче, в веб разработке есть так называемые курсоры, которые никакими курсорами на самом деле не являются. Это обычные WHERE условия в SQL! Но за каким-то х***м это называется курсором.

Вот SQL получения первого списка постов для ленты:

SELECT id, title, created_at
FROM posts
ORDER BY created_at DESC, id DESC
LIMIT 20;

Далее браузер в http запросе для получения следующих 20 постов передает payload:

"last_created_at": "2026-01-15 12:30:00+00",
"last_id": 12345,

И бэк делает SQL запрос:

SELECT id, title, created_at
FROM posts
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 20;

Вот эта строка:
WHERE (created_at, id) < ($1, $2)
это и есть как бы наш курсор, хотя нифига это не курсор.

Такой запрос с псевдо-курсором намного быстрее, чем юзанье OFFSET когда постгрес читает все подходящие записи в таблице и тут же скипает часть их.
Показать полностью...
+2
59
1