myStack
890 subscribers
761 photos
15 videos
27 files
310 links
Меня зовут Ростислав и я разработчик.

Это мой личный блог.

Я пишу на Go, читаю книги про технологии и пишу об этих и других вещах сюда.


Книги:
https://bit.ly/rostislav-books

Личка:
https://t.me/Rostislaved

Сайт:
Rostislav.me
Download Telegram
Forwarded from Denis Sexy IT 🤖
А вот что она умеет генерировать уже сейчас; а помните были такие люди – «художники»? 🌚
👍1😱1
Крутяк) Разобрался, как писать код с дженериками в Го и реализовал множество.
👍2
15 Top-Paying IT Certifications for 2021
link
nice
😁2😢1💩1
I am calling the police

Нейросеть Dall-e-2 рисует картинки по фразам
👍3
Quality of living city ranking

link
О, новый вопросик появился при отклике на вакансию
Data race (или просто гонка)

Представим, что есть некий код, который запускает 2 параллельных потока, внутри каждого в цикле, например 1 млн раз, происходит одна операция:
а = а + 1
где а - одна и та же переменная (например глобальная).

Ожидаемый результат - a == 2 млн
Фактический результат - a < 2 млн. Точное значение всегда разное.

Так происходит потому что a = a + 1 для процессора на самом деле является не одной операцией, а тремя:
1. Взять из оперативки значение в переменной а и поместить ее в регистр процессора
2. Прибавить к этому значению 1 (результат суммирования лежит в регистре)
3. Сохранить результат из регистра в оперативную память

И при параллельной работе с этой переменной порядок этих операцией не гарантируется. То есть нет гарантии в каком порядке потоки ОС будут выполнять эти операции. Отсюда и возникает состояние гонки.

Пример.
Допустим есть 2 потока ОС. Работу начинает первый. a = 0
1 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
1 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
Переключение контекста (начал работу второй поток)
2 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
2 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
2 поток. Выполнил 3. (в регистре: 1, в оперативке а=1)
Переключение контекста (начал работу первый поток)
1 поток. Выполнил 3 (в регистре: 1, в оперативке а=1)

Таким образом, после того, как 2 потока сделали a = a + 1 в переменной лежит не 2, а 1.

Чтобы избежать состояния гонки надо запретить двум потокам одновременный доступ к общему участку памяти (Участок кода, где это происходит называется критическая секция).

Сделать это можно с помощью мьтекса (лок): до операции над критической секцией делаем Lock(), после операции над критической секцией делаем Unlock().

Суть этого в том, что пока один поток "держит" лок, то другой поток при попытке сделать Lock() блокируется и ждет, пока другой поток не сделает Unlock(). В результате этого все 3 операции для инкремента переменной всегда происходят атомарно и проблемы возникнуть не может.

Пример кода:
https://go.dev/play/p/BGzDCig5dGQ

package main

import (
"fmt"
"sync"
)

var a = 0

func main() {
var wg sync.WaitGroup

wg.Add(1)
go increment(&wg)

wg.Add(1)
go increment(&wg)

wg.Wait()
fmt.Println(a)
}

func increment(wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 1e6; i++ {
a = a + 1
}
}
👍2🔥1
У DeliveryClub есть крутая Pro подписка, которая делает доставку бесплатной во многих местах.

Стоит 100р в месяц (первый вообще 1р). С учетом того, что сама доставка без подписки 129р за 1 раз, то это очень выгодно.
1
btw если вас напрягает дублирование в чате и в канале, из одного из них или из двух можно ливнуть :)
Вк - мастер аналитики.
2й скрин - эта Елизавета
3й скрин - я
🔥3
Подход европейских и рускоговорящих рекрутеров.

(полезной инфы на втором скрине больше)

PS: европейские, пощадите..
🔥1