Pull to refresh
22
0
Дмитрий Попов @Popik

User

Send message
Если появится принципиально новый вычислитель с мощностью более 51% всей мощности сети, и он не будет задействован в майнинге, то тогда блокчейну конец. Получится переподписать всю историю с самого начала и создать альтернативную историю. Но тут *скорее всего* сыграет роль огромное количество пользователей блокчейна, которые быстро используют тот же вычислитель в целях майнинга, и тогда такой проблемы не будет.

С точки зрения того, чтобы взять и переделать первые блоки, а потом «приклеить» их к новым, это маловероятно, пока не обнаружена уязвимость в sha256, которая позволить делать прогнозируемые коллизии (но если она будет обнаружена сломается сразу весь механизм PoW, и блокчейну опять конец). Потому что если такая возможность будет, тогда можно будет и новые блоки модифицировать так, чтобы их не перемайнивать заново. Более того «векселя» в блокчейне имеют строго определенный формат, и вероятность того, что незначительное изменение в «векселе» позволит получить хеш-коллизию близка к нулю. Такую коллизию скорее более вероятно получить на целой цепочке ранних блоков, но получается, что нужно будет переподписать раннюю цепочку миллиарды раз, чтобы получить коллизию и «приклеиться» к новым блокам.
По моему данный пример наглядно иллюстрирует тотальное непонимание системы блокчейн и того, зачем она нужна. В приведенном примере полностью отсутствует майнинг, который как раз гарантирует защиту децентрализованный данных при помощи PoW. Какой смысл хранить последовательные блоки, хранящие хеш предыдущего, если в такой системе можно обновить случайный блок в цепи, а потом за секунду перехешировать всю цепочку? Чем это вообще лучше обычной реляционной БД, которая уже готова, и которая предоставляет уровень «защиты от подтасовки» ровно такой же, то есть нулевой?
Достаточно известная примочка в кругах тюнеров. Позволяет получить дополнительные 10-20% мощности на сильно наддутом моторе. На атмосферниках смысла практически не имеет, дает слишком незначительный приход мощности и экономию на уровне погрешности измерений. Однако для турбомотора подача водяной пыли в цилиндры позволяет сдвинуть порог детонации, таким образом можно увеличить углы опережения зажигания и сделать более бедную смесь, что повышает КПД, снижает расход и повышает мощность. Также есть эффект повышения давления в цилиндре за счет испарения воды и появления пара. Насчет ржавения двигателя ничего сказать не могу, на моторах, которые я видел и разбирал ржавчины не было. Зато есть бонус для моторов с непосредственным впрыском, где топливо не проходит сквозь впускные клапана и не омывает их. Подача воды (или водометанольной смеси, что еще круче) отлично отмывает нагар с клапанов. Для распределенного впрыска, разумеется, такого бонуса нет, так как клапана и так омываются бензином.
А в чем фишка снимать в RAW, а потом дергать оттуда превью джипег?
А в чем проблема исправить кусок написанного кода а не реализацию интерфейса, ну допустим там не использовать другого наследника, а просто изменить реализацию? В этом абсолютно нет никакой разницы, однако тут интерфейсы преподносятся как великое благо. Интерфейсы не дают большей гибкости, чем конкретная реализация, это я и хочу сказать. Это инструмент для проектирование иерархии классов в подходящих для этого задачах.
Не уверен, что такое возможно. Вот например в вашем примере, интерфейс — это копия конкретной реализации. И как можно первично все предусмотреть, ведь делая интерфейс все обычно опираются на то, что уже будет под ним. Это как сказать, что можно например спроектировать отличный интерфейс для _любой_ базы данных, изначально разрабатывая его под какую-то конкретную одну…
Если команда хорошо знает код, который пишет, то обычно быстро все становится понятно. А если команда большая, и никто уже ничего не знает, то да, юнит-тесты — единственный выход.
Например можно использовать интеграционные тесты :)
Кстати расскажите, а как можно использовать юнит-тесты для проверки корректности интеграции двух систем?
Тут есть еще такой аспект. Чаще всего, как я уже и говорил, интерфейсы делаются не первично, а как прокси для уже некоторой существующей реализации, поэтому говорить о полноценной абстрактности достаточно сложно. Единственное, что чего они отлично подходят, так это для юнит тестов, но это уже совсем другая история.

Получается, что на самом деле в случае интерфейсов у нас есть такой же неуниверсальный код, как и «конкрит» реализация, только в одном случае для внесения правок нам надо написать новый класс наследник от интерфейса и кинуть его в контейнер, а в другом стереть код в конкрит реализации и написать новый. Разницы по-моему вообще никакой, только в первом случае у нас есть код интерфейса + код класса, в во втором просто код класса. Если я не прав, прошу пояснить.

А если вдруг потребовалось нечто, что требует изменения интерфейса, какая разница, тащить через весь код обновленный интерфейс, или конктрит реализацию?
Получается, что вместо одного программиста, Вам будет нужно десять. Все еще хотите код покрытый тестами?

А вы не думали, что такая гадостная вещь, как регрессия, в основном происходит не потому что в команде одни осьминоги с кривыми щупальцами, а потому что в проекте там много кода, что нужна большая команда, а в большой команде никто уже целиком картину не видит и может запросто написать код, который сломает старый? Получается, что юнит-тесты это отличный механизм борьбы с регрессией, но применение этого подхода косвенно регрессию провоцирует…
И вообще скажите честно, Вам машина нужна чтобы на ней ездить или детали менять?
Вы не поверите, но в современных машинах обычно можно поменять только крупные узлы. Например поменять шестеренку в коробке передач или флап во впускном коллекторе невозможно, нужно покупать только новый узел или колхозить. А вот на старых тазиках можно поменять и купить ЛЮБОЙ болтик, вообще все что угодно, но что-то тазики не очень популярны. Зато машина становится легче, проще, дешевле. И да, такие машины покупают.
Жизнь вообще сложная штука. Но хорошей практикой является делать то, что от тебя требуется, а не то, что считаешь «правильным». Если заказчик хочет получить учет автомобилей, но стоит делать программу с учетом тяжелой строительной техники и детских колясок. Это просто усложнит код, повысит затраты на разработку и увеличит штат сотрудников. И Вы же не ожидаете, заказав в макдоналдсе гамбургер подождать лишний час, что вам сделали такой бургер, который при желании может стать и блинчиком?

Тут возникают следующие нюансы, во первый в какой-то момент кода станет так много, что например понадобится больше разработчиков. Только вот увеличение штата не приводит к линейному росту производительности, а порой существенно ее снижает. Для того, чтобы грамотно организовать процесс разработки в большой команде, нужен поистине одаренный руководитель, ведь руководство большой командой это искусство, которое порой в разы сложнее и так непростого программирования. Вашей команде возможно очень повезло, если у Вас есть такой замечательный лидер. Но даже с отличным руководителем затраты на кросс-функциональное взаимодействие могут составить бОльшую часть времени работы команды, а это неэффективно. Также в большой команде начинаются бои за лидерство и перетягивание одеяла. Это неизбежно, а это наносит существенный урон качеству продукта в целом.

Другим же альтернативным подходом, к которому я склоняюсь на данный момент, является организация работы микрокомандами по несколько человек (от 2 до 4), которая каждая делает свой проект, а с другими командами общается только на уровне интеграции. В микрокоманде затраты на взаимодействие минимальны, так как при нормальной квалификации и дисциплине возможна работа даже без багтрекеров и внятной документации (а написание документации и ведение тасков — это значительная нагрузка на программистов, которая отвлекает их от основной задачи). При такой организации достаточно одного грамотного архитектора, который в целом не лезет в кишки проекта, и лишь контролирует интеграционное взаимодействие и общую адекватность решений.

Однако для того, чтобы иметь возможность использовать микрокоманды необходимо ограничивать себя в размерах кода, так как 1-2 человека просто не смогут адекватно поддерживать сотни тысяч строк кода и тесты к ним. С одной стороны нет документации (о ее необходимости я бы конечно поспорил, я сторонник простого и самодокументируемого кода), нет тестов, нет витьеватых суперрасширяемых конструкций, но с другой стороны, небольшой объем кода позволяет в нем намного лучше разбираться и значительно сократить количество регрессий, а также повысить скорость и эффективность работы.

Не угадали, я несколько лет работаю в достаточно крупной софтверной компании, разрабатывающей серьезные банковские продукты. Участвую в нескольких проектах и наблюдаю за многими другими, так как приходится с ними интегрироваться и проводить консультации.

Из того что я вижу, я и делаю выводы. Команды, которые делают продукт, который работает, обычно достаточно спокойно относятся к качеству кода, и предпочитают функционал качеству кода. Другие же команды, которые могут сидеть год, а потом оказалось, что они за все время написали только юнит-тесты, обычно даже до первого релиза не доходят, так как просто не успевают в сроки, и иногда проекты сворачивают, как неуспешные.
В этом случае иерархия классов как раз уместна.
Но например стоит ли, проектируя автопарк, делать не IVehicle, а например IAsset, который в свою очередь расширяет ISomething, который расширяет IUniverse? А также сделать так, что машины могут быть как с обычными двигателями, так и потенциально с ядерными (разумеется с интерфейсом обычного)?
Задача грамотного программиста — удержать свой проект в «масштабах 100 строчек». Вы будете удивлены, какие сложные приложения могут быть написаны малым количеством кода. Также как и простейшее приложение из пары табличек может занимать сотни тысяч строк сомнительного кода.
Понятное дело, что каждая задача требует решения, которое порождает лишние строчки, но зачем целенаправленно раздувать свой код лишними конструкциями, для меня до сих пор остается большой загадкой.

Даже если проект правда огромен, наиболее разумным решением будет разбить его на много «конкрит» кирпичиков из по вашему мнению «неподдерживаемого» кода, и красивое и в то же время простое ядро, в которое изменения вносятся крайне редко и при большой необходимости. Весь остальной мусор живет в одноразовых кирпичиках. Именно такие проекты имеют шанс разрабатываться быстро, могут пережить большую команду и хреновых специалистов.
1) это же очевидно, что нет более постоянно решения, чем временное. Даже если начать переписывать, опять же очень не факт что новый проект вообще завершится, а не утонет в утехах тру программистов
2) в хорошей системе все делается лучше, только вот не факт, что паттерны и модные фишки облегчат жизнь, а не загонять разрабов в полный рефакторинг
3) я имел в виду задержки в разработке, не в коде. От кода обычно проблем меньше, чем от человеческого фактора
Ну хорошо, у нас было 10 строчек кода, стало 100. Из новых 100 строк около 20 менять точно не надо будет.
В первом решении не надо будет менять 0 строчек, а во втором 20.
По моему достойный результат :)
К сожалению многие программисты забывают, зачем они делают свою работу. Стремятся написать «идеальный код», но не думают о том, какие задачи они решают и для чего.

Рассмотрим несколько примеров:
1) команда делает некоторый продукт, который при правильном позиционировании может стать индустриальным стандартом. Однако не только эта компания занимается этим, и то, насколько быстро продукт будет выведен на рынок, будет играть решающую роль в его дальнейшем развитии
2) команда разработки и поддержки некой системы документооборота внезапно получает новые правила для набора документов, регламентируемый государством. Например система учета зарплаты. Если до конца месяца система не будет внедрена и по ней не будет произведен новый расчет зарплат и выписок, то в лучшем случае компания попадает на огромные штрафы, или на штрафы попадают ее клиенты
3) в банковской сфере задержка даже в день может нести колоссальные убытки

И что, в каком нибудь из этих случаев ответ тимлида о том, что не успеем, мол еще не все юнит тесты написаны и не все иоки бахнуты будет адекватен?

Так что скорее те проекты, где есть много времени — как раз они тепличные
Потому что если продукт пишется под девизом «у нас достаточно времени, чтобы сделать хорошо», то обычно он уходит в пучину треша и угара
1
23 ...

Information

Rating
Does not participate
Location
Москва и Московская обл., Россия
Date of birth
Registered
Activity