All streams
Search
Write a publication
Pull to refresh
193
0.8

Программист

Send message

Работа peer2peer в идеале никак не зависит от доступности сервера. Ну если вдруг не будет работать (ну вдруг, всякое бывает), то включить звонки через прокси никогда не поздно.

И если в С/С++ это естественно из-за адресной арифметки, то в Java/Javascript/C# это было сделано из соображений «похожести» синтаксиса на С++. То есть это просто историческое наследие, а ведь могло бы быть и так:

Начинал в школе с паскаля (и изначально привык к индексации с 1), но мне кажется, что индексация с нуля намного удобнее. Иначе вылезают проблемы с тем, что при умножении индекса на число первый индекс становится уже не первым.
Например, если хранить "двухмерные" данные в одномерном массиве:
arr[y * width + x] vs arr[(y-1) * width + x]
Или пропустить каждый второй элемент:
arr[2*i] vs arr[2*i-1]
А если полезть в кастование указателей, это же вообще жесть получится. Допустим, есть массив int32_t, чтобы прочитать первый байт числа ints[i] как у массива byte, нам придётся залезть по индексу bytes[(i-1)*4 + 1] = bytes[4*i - 3].


Какая-то логика в этом есть — остальные байтики будут лежать по адресам 4*i-2,4*i-1 и 4*i, но вычитать из индекса чиселки просто ради того, чтобы начало осталось началом — неудобно.
В выскороуровневых языках уже не важно, там берётся какой-нибудь foreach, который сам бегает по любым коллекциям.

В предложениях типа «пусть y = 2x» это именно присвоение (что обозначено дополнительным «пусть»

Не согласен. Присвоение некоммутативно, в отличие от равенства. Утверждение типа "пусть" или "предположим" накладывает ограничение на x и y. Если что-то из них задано, то ограничение позволяет вычислить вторую переменную.
Если же неизвестно ни одного ни другого, то утверждение вида "… = ..." всё равно имеет смысл, в отличие от присваивания.


Вот реальный пример: надо найти массу по весу тела.
Я напишу: "по закону Ньютона P = mg, поэтому m = P/g" Присвоением можно разве что вторую формулу назвать (но я её всё равно считаю частным случаем равенства)

Шарфом можно лицо по самые очки замотать. Главное — приспособиться, чтобы тёплый воздух от дыхания шёл не вдоль лица к очкам (запотевают за один выдох), а куда-нибудь вниз или сквозь шарф. (Ну или забить и снять очки). Удобство в том, что шарф всегда можно сдвинуть на шею, если он становится не нужен, да и окружающие удивления не испытывают. Из недостатков — шарф намокает от дыхания, но я в -10 -15 больших проблем не испытывал, под шарфом всё равно тепло.


Ещё капюшон неплохой эффект даёт — дующий в лицо ветер затормаживается где-то заранее и щёки не мёрзнут.

я в скале иногда определяю := для присвоения по значению. Поведение = там изменить нельзя — оно всегда по ссылке для ссылочных типов.
Ещё забавно: в go есть :=, причём там используется наоборот — для объявления переменной с присвоением значения, a = для присвоения!

Кстати, а если к дрону можно подключаться всевозможными способами и там внутри Linux, почему бы не написать своё ПО для него и не настроить так, чтобы закрыть дыры?
Я бы поигрался — было бы круто сделать, чтобы дрон сам адекватно летал при потере сигнала и прочих необычных условиях.

В Вашем примере сильно заметная точка по центру — не одна, а целая куча совпадающих. И усреднённая по небольшой окрестности плотность точек будет примерно одинаковой. Картинка об этом умалчивает. Чисто по глазок — при построении графика знаменатель дроби был не больше 20, поэтому можно "размыть" картинку где-то на 0.05 и избавиться от линий.


Допустим, у нас дроби, где в знаменателе что-то вроде тысячи. Эффект квантования из-за целых чисел расположит точки друг от друга расстоянии около 0.001. Если мы размоем каждую точку (например, заменим на маленькое распределение гаусса с шириной больше 0.001), то итоговая картинка будет гладкой и без заметных точек. В общем-то, это размытие и не особо нужно — в статье графики в ширину меньше 1000 пикселей, даже если там заменить точку 1250/2500 на 1251/2500 или на 1259/2500, она вообще никуда не сдвинется.


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

Т.е. вы утверждаете, что на всех участках должны были быть одинаковые результаты по явке и по голосованию?

Какая вероятность того, что 2 случайно выбранных участка из 26 будут обладать самой низкой явкой? 2 / (26 * 25) = 0.003.
А тут идейные наблюдатели пришли на два участка и такое подозрительное совпадение случилось.

Если что, я последнее время на джаве не писал. Могу ошибаться. Итак, ссылочки:



Часть неудобства при использовании связана с самим языком (тут уж ничего не поделать, не менять же весь язык ради одного класса). Например, метод orElse(new SomeObject()) в скале принимает лениво вычисляемое значение, в нём можно написать какую-нибудь логику типа создания нового элемента. Или, например, есть приятный синтаксис for (a <- option1; b <- option2) yield a+b, благодаря которому удобно работать с несколькими Option одновременно.


Часть неудобств вызвана именно реализацией класса (вернее, отсутствием некоторой функциональности). Почему в скале Option Serializeble, а в джаве — нет? И ещё — в скале Option довольно сильно похожа на маленькую коллекцию — есть приятные методы типа foreach, exists, forall, contains. С их помощью код становится лаконичнее. (В джаве похожая функциональность есть у стрима, в который можно превратить Optional, но мне такой способ кажется немного странным, тем более превращать его придётся вручную).


Ещё часть неудобств вызвана стандартной коллекцией. Например, я не могу в джаве от HashMap получить Option. Конечно, это всё мелочи, можно написать что-нибудь типа Optional.of(hashMap.getOrDefault(key, null)), но получится куча некрасивого кода.


В итоге получается, что код с использованием Option в скале выглядит коротким и зачастую более простым, чем с проверками на null, а в джаве — наоборот. И чтобы Option хорошо вписался в язык, придётся внести кучу изменений, которых делать, скорее всего, не будут.

Других возможностей его применения я не вижу.

В джаве особых возможностей и нет.


В других языках, где это органично вписано в язык, испольуется очень широко. Kotlin: прямо в системе типов есть типы, которым нельзя присваивать null (кстати, обёртки там нет, никакого снижения производительности). Rust: нет нулевых указателей, но зато есть оптимизация, что Option с указателем — не обёртка, а просто указатель. Scala: Option реализована как обёртка, обладает кучей возможностей и интегрирована в стандартную библиотеку. Например, у всех коллекций есть методы и для возвращения обычных значений и для Option, можно использовать что хочется в зависимости от ситуации.

Ещё c помощью summary_writer.add_run_metadata(...) можно записать информацию о выполнении. Для каждой вершины графа — потребление памяти и затрачиваемое на вычисление время.


Для того, чтобы график отобразился в TB, приходится ждать до 15 минут.

Странно. У меня график обновляется с интервалом в 1-2 минуты.

Идея раз — польскую нотацию надо знать. Она простая (никаких приоритетов, просто стек и операции) и очень близка к тому, как это выражение потом будут вычислять. (например, байткод jvm или питона содержит команды типа "загрузить/удалить из стека" и "взять с вершины N элементов, сделать что-то и положить результат обратно на стек").


Теперь про алгоритм пинг-понг. Он воспринимается проще, но в нём есть фатальный недостаток — он постоянно бегает туда-сюда по строке и меняет её. Т.е., вместо стека для алгоритма ОПН в пинг-понге используется чтение-запись из памяти размером со входные данные.


Классический алгоритм читает вход посимвольно, и это даёт интересные возможности:


  • он может обрабатывать большие файлы, последовательно читая их байт за байтом без необходимости держать весь файл в оперативной памяти.
  • его можно компоновать с другими обработчиками — например, собрать цепочку из алгоритмов — первый убирает комментарии из строки, второй — парсит числа и операции (чтобы потом не развлекаться сборкой числа из цифр), третий — преобразует в постфиксную нотацию, четвёртый тут же вычисляет результат.

Классический алгоритм не использует рекурсию. Вся память, что ему нужна — стек. Проще уже некуда.

Длина подаваемой на вход строки не может сократиться — какая есть, такая и есть.

Может: "(a + b) * c" vs "a b + c *". Обычно принято между операторами ставить пробелы, и в этом случае их и слева и справа по 4 штуки. А вот скобок справа нет.


Приоритетность операций определяется математикой. Какие могут быть разночтения?

У чего приоритет больше — у >> или | или ^? Это не имеет отношения к математике и может различаться от языка к языку. Я такие моменты не всегда помню, операторов куча, иногда лучше скобки поставить.


P.S. я не фанат польской нотации, но Ваши аргументы неубедительны.

Конкретно про войну — это называться «прятаться за спинами других».

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


P.S. Я провёл месяц на военных сборах и очень сильно разочаровался.
О да, я отстрелял в сторону мишени 5 или 7 патронов — в общем, это всё. Зато умею маршировать, убирать территорию, выдёргивать траву между бетонными плитами и делать вид, что я очень занят. Ах да, я ещё умею воротнички подшивать, несмотря на то, что в современной форме они не нужны.
Обороноспособность страны ну ни разу не повысилась, это был тупая трата моего времени и здоровья. (Я, наивный, думал, что нас будут учить чему-нибудь типа тактики, ориентирования на местности и прочим штукам. Ничего не было.) Насколько я понимаю, у срочников то же самое, но в бОльших масштабах.

Идея читать переписку становится максимально бредовой, если учесть, что мессенджер используется не только нашими согражданами.


Вот переписываются гражданин России с иностранцем в телеграмме. Всю переписку выдавать точно нельзя. Передавать сообщения только первого? А если это иностранец, купивший симку в России? А если это человек с двойным гражданством? А если он уже 10 лет живёт за границей? На основании чего решать, какого пользователя к какой юрисдикции относить? Предложить при регистрации указать страну? Окей, я укажу Непал, что дальше? (Просто так взять и расшифровать всю переписку на территории России нельзя — будут нарушены права иностранцев (да и наши, но на них уже всем наплевать))
А если (раз уж так любят оправдывать всё борьбой с терроризмом) приедут террористы из другой страны, то их переписку будет нельзя прочитать?
Тут есть две крайности — раскрывать всю переписку (но, блин, пусть не удивляются, что к переписке, кроме фсб, захотят иметь доступ АНБ и службы других стран, а дамп сообщений рано или поздно сольют в открытый доступ), либо не раскрывать ничего.

Не волнуйтесь, с линуксом вы будете тратить упомянутые два вечера еженедельно :)

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


Запускал mint на нетбуке с 1гб памяти. Тормозит сильно, но если отключить графическую оболочку и подключаться по ssh, тормоза пропадают и ос занимает всего лишь 50мб оперативки. Само по себе ядро линукса к железу совсем нетребовательно.

В Вашем примере строчки букв по длине не сильно отличаются от строчек иероглифов. Но у иероглифов намного больше всяких мелких чёрточек, квадратиков и прочего (т.е., их следовало бы печатать намного крупнее), а буквы читаются одним махом, потому что их всего лишь 30 и они по внешнему виду максимально простые и различающиеся.

Мне тоже не понятен этот момент. Там же чётко написано ограничение


extension Optional where Wrapped == String { ...

Я так же могу в котлин написать:


class Wrapper<T>(val t: T)

fun Wrapper<String>.printMe() {
    println(t)
}

Однако компилятор защитит вас и не скомпилирует этот код. Но если вы добавите больше таких расширений — ваша автоподсказка будет забита мусором.

В котлине автоподсказка мусором не забивается. Может, виновата ide, а не язык?

Добавлю свои 5 копеек: я анализирую игры, в которые играл или смотрел происхождение. Не на уровне "графика красивая, геймплей уныл", стараюсь разобраться в причинах — выделяю неудачные и, наоборот, удачные моменты в геймплее, пытаюсь понять, почему разработчик сделал так, а не иначе. Иногда получается, что внесение вроде бы маленького изменения потребует ещё кучу переделок, которые перевенут игру.
И чтобы мои размышления не пропали, записываю их. Так же делаю записи, когда читаю что-то интересное.


P.S. Кстати, могу ли я взять какую-нибудь главу из книги по геймдизайну, которая не издавалась на русском, перевести и опубликовать на хабре? Ко мне никаких претензий со стороны правообладателей не возникнет?

Выше имелись ввиду матрицы 4*4, которые активно используются в 3д графике (и в 2д тоже — например, для сортировки спрайтов по глубине). Без начальных знаний линейной алгебры далеко не уйти.
Я начинал с книжки F.Dunn I.Parberry "3D math primer for graphics and game development". Она на английском, но зато начинается с самых самых азов типа векторов и их свойств, а потому можно потихоньку привыкнуть к английским обозначениям и прочитать её целиком. Кроме того, благодаря этой книжке я осознал суть кватернионов и потом спокойно использовал их. Там есть примеры на С++ с реализацией кватернионов, матриц и простейших моделей освещения.

Information

Rating
1,795-th
Location
Белград, Сербия
Registered
Activity

Specialization

Software Developer, ML Engineer
Kotlin
Scala
Java
Python
Neural networks
Algorithms and data structures
Android development
OpenGL