• Побег из гнезда успеха или Проблемы больших компаний

      Привет, Хабр! Говорят, чистосердечное признание смягчает наказание. Каюсь — большая часть статьи будет откровенным копипастом чужого текста. Прошу модераторов не судить строго и считать огромной цитатой. Потому что лучше не скажешь. Потому что я, вы, ты, читатель, — все мы там были или можем быть. В больших межгалактических корпорациях компаниях, которые заманивают офисами, всевозможными плюшками из рога изобилия, самокатами в коридорах и прочими релакс-капсулами, но редко говорят, что будет взамен. А взамен будут бесконечные совещания, легаси, инерция и… мать его, одинокое ощущение себя маленьким винтиком какой-то адовой машины. Начну со своей истории — в одном абзаце. А потом — просто откровенная бомба — текст, каждое слово которого крепко отозвалось во мне, вроде суровом дядьке.


      Читать дальше →
    • Пора убить веб

      • Перевод
      Что-то происходит. Люди недовольны. Призрак гражданских беспорядков преследует наши программистские сообщества.

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


      Это ты, хакер фронтенда
      Читать дальше →
    • Странности Generic типов Java

        Я множество раз слышал о том, что дизайн Generic типов в Java является неудачным. По большей части претензии сводятся к отсутствию поддержки примитивных типов (которую планируют добавить) и к стиранию типов, а конкретнее — невозможности получить фактический тип параметра в рантайме. Лично я не считаю стирание типов проблемой, как и дизайн Generic-ов плохим. Но есть моменты, которые меня порядком раздражают, но при этом не так часто упоминаются.


        1


        Например, мы знаем, что метод Class#getAnnotation параметризован и имеет следующую сигнатуру: public <A extends Annotation> A getAnnotation(Class<A> annotationClass). Значит, можно писать вот такой код:


        Deprecated d = Object.class.getAnnotation(Deprecated.class);

        Тут я решаю вынести Object.class в отдельную переменную и код перестаёт компилироваться:


        Class clazz = Object.class;
        // incompatible types:
        // java.lang.annotation.Annotation cannot be converted to java.lang.Deprecated
        Deprecated d = clazz.getAnnotation(Deprecated.class);

        Где я ошибся?

        Читать дальше →
      • Встречайте Kotlin 1.1: JavaScript, корутины и многое другое

        • Перевод

        Мы рады представить вам Kotlin 1.1, новую версию языка программирования Kotlin.


        Kotlin 1.1

        Наша цель — сделать выразительный статически типизированный язык, на котором можно эффективно писать все компоненты современного приложения. Сегодняшний релиз делает два важных шага в этом направлении.


        Читать дальше →
      • Пишем MVP приложение на Kotlin под Android



          Разработка приложений на Kotlin под Android набирает популярность среди разработчиков, однако статей в русскоязычном сегменте Интернета довольно мало. Я решил немного подправить ситуацию, и написать туториал по разработке приложения на Kotlin. Мы напишем полноценное приложение с использованием всех трендовых библиотек (кроме RxJava) в мире Android-разработки. В конце у нас должно получиться расширяемое и легко тестируемое приложение (сами тесты мы писать не будем).
          Читать дальше →
        • Kotlin 1.0. Задай вопрос команде

            На этой неделе случилось важное для нас событие — вышла первая версия языка программирования Kotlin! Так как почти вся разработка Kotlin велась в Питерском офисе компании JetBrains, многие хабровчане уже знают, что такое Kotlin и пробовали его на практике, поэтому этот пост больше для комментариев: задавайте любые вопросы и команда Kotlin ответит. Мы онлайн!

            image

            Читать дальше →
          • Полвека «универсальным машинным языкам» (1966—2016): прошлое, настоящее, будущее

              КДПВ

              Прошлое


              Повествование можно начать с 1962 г., когда в Кембриджском университете началась работа над CPL («Cambridge Programming Language») — «усовершенствованным вариантом» ALGOL-60. К работе над языком подключился аспирант Мартин Ричардс; главной сложностью в реализации нового ЯП ему показалась необходимость ручного портирования компилятора для разных компьютерных платформ. В частности, когда кембриджский EDSAC-2 заменили на Atlas-2, разработчики CPL потратили много времени на портирование своего компилятора для новой платформы.

              Диссертация Мартина была посвящена «само-компилирующемуся» CPL: разработанный Мартином компилятор был написан на сильно упрощённом варианте CPL, компилятор которого несложно было написать на тогдашнем макроассемблере. Перенос CPL на новую платформу теперь можно было выполнить в два шага:
              1. Вручную пишем компилятор «упрощённого CPL»;
              2. Компилируем им компилятор «полного CPL».

              На этом Мартин не остановился, и разработал BCPL — систему для разработки переносимых компиляторов. Компилятор BCPL генерировал псевдокод, названный Мартином «OCODE».
              OCODE выглядел примерно так:
              OCODE «расшифровка» («procode»)
              94 5 L1 83 73 69 86 69
              95 4
              42 0
              42 0 40 2 14
              83
              42 0 42 1 40 2 14 83
              42 2
              40 3 42 1 15
              92
              85 L5
              90 L6
              42 1 40 4 40 2 14 83
              40 4 42 1 14 80 4 
              90 5 40 4 40 5 88 L6
              91 4
              42 2 40 3 42 1 15 92
              85 L7
              90 L8 40 4 40 2 14
              8 87 L9
              40 4 42 2 11 92
              85 L11
              90 L10
              42 0 40 6 40 2 14 83
              40 4 40 6 14 80 6
              90 L11
              40 6 40 3 22 86 L10
              91 6 90 L9
              40 4 42 1 14 80 4
              90 L7 40 4 40 5 88 L8
              91 4 97 103 0
              
              ENTRY 5 L1  'S' 'I' 'E' 'V' 'E'
              SAVE 4
              LN 0
              LN 0 LP 2 PLUS
              STIND
              LN 0 LN 1 LP 2 PLUS STIND
              LN 2
              LP 3 LN 1 MINUS
              STORE
              JUMP L5
              LAB L6
              LN 1 LP 4 LP 2 PLUS STIND
              LP 4 LN 1 PLUS SP 4
              LAB L5 LP 4 LP 5 ENDFOR L6
              STACK 4
              LN 2 LP 3 LN 1 MINUS STORE
              JUMP L7
              LAB L8 LP 4 LP 2 PLUS
              RV JF L9
              LP 4 LN 2 MULT STORE
              JUMP L11
              LAB L10
              LN 0 LP 6 LP 2 PLUS STIND
              LP 4 LP 6 PLUS SP 6
              LAB L11
              LP 6 LP 3 LS JT L10
              STACK 6 LAB L9
              LP 4 LN 1 PLUS SP 4
              LAB L7 LP 4 LP 5 ENDFOR L8
              STACK 4 RTRN ENDPROC 0
              
              ; заголовок процедуры
              ; стековый кадр (два параметра и две локальные переменные)
              ; поместить на стек число 0
              ; поместить ещё один 0, прибавить к нему 2-ой элемент стека
              ; записать в массив на вершине стека значение под ним
              ; всё то же самое для 1-ого элемента массива
              ; поместить на стек число 2
              ; вычесть единицу из значения 3-его элемента стека
              ; записать результат в локальную переменную
              ; перейти к метке L5
              ; объявление метки L6
              ; взять 4-ый элемент стека, записать в массив по этому индексу 1
              ; прибавить к 4-ому элементу стека 1, записать результат обратно
              ; L5: перейти к метке L6, если 4-ый элемент стека <= 5-ому
              ; объявление, что на стеке сейчас четыре элемента
              ; вычесть единицу из значения 3-его элемента стека
              ; перейти к метке L7
              ; L8: сложить 4-ый и 2-ой элементы стека
              ; прочитать значение по этому адресу; если это 0, перейти к L9
              ; умножить 4-ый элемент на два
              ; перейти к метке L11
              ; объявление метки L10
              ; взять 6-ой элемент стека, записать в массив по этому индексу 0
              ; прибавить к 6-ому элементу стека 4-ый, записать рез-т обратно
              ; объявление метки L11
              ; перейти к метке L10, если 7-ой элемент стека меньше 4-ого
              ; на стеке сейчас шесть элементов; объявление метки L9
              ; прибавить к 4-ому элементу стека 1, записать результат обратно
              ; L10: перейти к L8, если 4-ый элемент стека <= 5-ому
              ; на стеке четыре элемента; окончание процедуры
              (Для экономии места, последовательности команд записаны в одну строчку. Мартин в своём руководстве по BCPL поступает точно так же.)

              Исходный код на BCPL:
              LET sieve(workvec, vecsize) BE
              {
                workvec!0 := 0
                workvec!1 := 0
                FOR i = 2 TO vecsize-1 DO workvec!i := 1
                FOR i = 2 TO vecsize-1 DO
                  IF workvec!i DO
                  { LET j = 2 * i
                    WHILE j < vecsize DO
                    { workvec!j := 0
                      j := j + i
                    }
                  }
              }
              
              В более новых версиях OCODE добавилась поддержка чисел с плавающей точкой (соответственно, набор поддерживаемых опкодов почти удвоился), а также удалили опкод ENDFOR — вместо него генерируется пара LE JT.

              Среди «универсальных машинных языков» OCODE уникален тем, что метки в нём определяются специальными инструкциями — т.е. для интерпретации программы её нужно сначала всю загрузить в память, и найти в ней метки.
              — а отдельная программа, кодогенератор, превращала файл с таким псевдокодом в исполнимую программу для конечного процессора. OCODE сохранялся в виде текстового файла из десятичных чисел, разделённых пробелами и переводами строк: в то время, когда OCODE разрабатывался, привязка формата файла к конкретному размеру байта ограничивала бы переносимость такого файла.

              Компилятор BCPL(1) поставлялся в виде OCODE, и чтобы перенести его на новую платформу, нужно было:
              1. Вручную написать интерпретатор псевдокода(2) (на любом языке, хоть на Бейсике);
              2. Адаптировать кодогенератор,(3) написанный на BCPL, для своей платформы;
              3. Запустить под интерпретатором (2) компилятор BCPL (1), скормить ему кодогенератор (3), и получить на выходе исполнимый файл кодогенератора(4);
                • Интерпретатор (2) нам с этого момента больше не нужен.
              4. Прогнать через кодогенератор (4) псевдокод компилятора (1), и получить на выходе исполнимый файл компилятора.


              Такой подход означал, что для переноса компилятора на новую платформу требуется лишь самый минимум низкоуровневого программирования; и действительно, реализация BCPL была завершена к 1967 г. — раньше, чем была завершена реализация CPL, начатая на несколько лет раньше!

              Достоинства BCPL применительно к системному программированию вдохновили Кена Томпсона на создание языка Би, а тот — коллегу Кена, Денниса Ритчи, на создание Си. Именно из BCPL пошла традиция обозначать {фигурными скобками} блоки программы, и именно на BCPL была написана первая программа «Hello, World!».
              GET "libhdr"
              
              LET start() = VALOF
              { writef("Hello*n")
                RESULTIS 0
              }
              
              Более важная нам причина, по которой BCPL вошёл в историю: OCODE — первая универсальная «архитектура набора команд» (ISA), т.е. «виртуальная машина», не привязанная ни к какой конкретной аппаратной платформе с её особенностями. BCPL, таким образом — первый язык программирования, соответствующий парадигме «Write once, run anywhere» (WORA): программу на BCPL можно распространять в скомпилированном виде, и её можно будет запустить на любой платформе, для которой существует OCODE-кодогенератор.
              Читать дальше →
            • Про Бурали-Форти, Пуанкаре и то самое определение единицы

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

                image

                Наверняка также вы задавались вопросом: что, чёрт подери, здесь написано? Формула из этой цитаты интересна тем, что у человека, имеющего высшее математическое образование, этот вопрос возникает столь же неумолимо, как и у любознательного семиклассника. У нелюбознательных семиклассников несколько иной круг интересов, выходящий за рамки данной статьи; однако даже они не откажут себе в удовольствии похихикать над «этими чокнутыми ботаниками», или как оно там формулируется на современном молодёжном сленге.

                В нижеследующем тексте я раскрою перед вами тайну этого загадочного сочетания символов. Пожалуйте под кат, однако помните поучительную историю о любопытной Варваре, которой на базаре рассказали про парадокс Банаха-Тарского, отчего она сошла с ума, разрезала себе нос на конечное количество частей и склеила из них рогатую сферу Александера.
                N.B. Я предупреждал.
              • Про модель, логику, ООП, разработку и остальное

                  Часто ли вы задумываетесь – почему что-то сделано так или иначе? Почему у вас микросервисы или монолит, двухзвенка или трехзвенка? Зачем вам многослойная архитектура и сколько у вас вообще слоев? Что такое бизнес-логика, логика приложения, презентационная логика и почему все так разделено? Посмотрите на свое приложение – как оно вообще спроектировано? Что в нем и где находится, почему это сделано именно так?
                  Потому что так написано в книжках или так говорят авторитетные личности? Какие ВАШИ проблемы решает тот или иной подход/паттерн?
                  Даже то, что на первый взгляд кажется очевидным, порой бывает очень сложно объяснить. А иногда, в попытке объяснения, приходит понимание того, что очевидные мысли были и вовсе ошибочны.
                  Давайте попробуем взять какой-нибудь пример и изучить на нем эти вопросы со всех сторон.
                  Читать дальше →
                • Критерий выгодности подстановки и динамическая профилировка

                    image

                    Продолжаю тему межпроцедурных оптимизаций, введение в которую можно найти в предыдущем посте. Сегодня хочется немного порассуждать о подстановке функции (inlining) и о том, как подстановка влияет на производительность приложения.
                    Читать дальше →
                    • +28
                    • 7,2k
                    • 2