Category: Ruby

30
Июн
2021

👨‍🎓️ 26 ресурсов для изучения Ruby и Ruby on Rails в 2021 году: курсы, книги, видеогайды, подкасты и блоги

Раньше приложения на Ruby не отличались высокой скоростью выполнения, но проекты на этом языке появлялись сотнями. Сейчас создатели языка провели работу над ошибками и его будущее стало намного светлее. Разберемся, где можно изучить Ruby и …

11
Июн
2021

🗣 «Я даже не видел себя разработчиком, это было просто хобби»

Александр – разработчик на Ruby c семилетним стажем. Он рассказал нашему корреспонденту, какие сложности встречаются в карьере программиста, можно ли стать профессионалом без высшего образования и какие мифы о Ruby – просто мифы.

  • Здравствуйте, Александр! Расскажите о себе.
  • Мне 28 лет. Закончил 11 классов и 1 курс физфака СПБГУ, потом бросил. Живу в Петербурге. Программирование изучал самостоятельно: в школе участвовал в олимпиадах по С++, а потом уже на работе учил.

  • С университетом история довольно простая, выбрал физический факультет, потому что в школе был хороший учитель физики. Выяснил в начале обучения, что физика мне не настолько интересна, насколько я думал, и я стал прогуливать пары.
  • Почему не перевелись на программирование?
  • Как ни странно, программирование тоже не особо интересно, если учится этому в вузе. Один из больших минусов вуза – программа для всех одна. В итоге первый курс для меня разделился на то, что я уже знаю, и то, что мне скучно. В любом случае, когда я начал получать какие то деньги, даже мысли продолжать учебу уже не было.
  • Как получилось, что вы стали Ruby-программистом?
  • Если говорить о выборе, я изначально изучал очень много языков, от Lisp до C++. Все это было последовательно. Когда я изучал Ruby и прогуливал универ, мы как то сидели с другом в кафе, пили чай и наш общий знакомый пришел с историей. Он написал биржевого бота для торговой площадки steam и начал зарабатывать на нем какие-то деньги. Я предложил бесплатно переписать его проект на Ruby, потому что это была интересная практика. История закончилась тем, что у меня был практический опыт разработки около года. Наш «стартап» закончился, когда владельцы Steam закрыли удобные пути вывода средств с биржи, и я пошел искать работу. На резюме с практическим опытом в Ruby отреагировали моментально.
Тогда я особо не задумывался, стоит изучать язык или нет, я изучал языки в очень бодром темпе и так совпало, что история с Ruby закончилась трудоустройством. Хотя я даже не видел себя разработчиком, это было просто хобби.

  • У вас не было проблем при трудоустройстве? Никто из-за корочки не отказывал?
  • У меня есть резюме, где написано, что диплома нет. Если у работодателя в требованиях ВО, то тоже первым не пишу. Даже не знаю, много ли потерял. В высшее образование для прикладного айти я в принципе не особо верю: это в основном нужно теоретикам. Если мне предложат на выбор человека с ВО без стажа и человека без ВО, но со стажем 1 год, я выберу второго.
  • При этом понятно, что опытные программисты математику все равно так или иначе знают, просто теоретикам надо из теории графов знать кучу всего, а практикам определение и какие алгоритмы для работы существуют.
  • Многие пишут, что Ruby не очень популярен в России, разве что для стартапов и релокаций. Это правда?
  • По поводу популярности языка в России – это немного миф, на рынке очень сильный дефицит кадров, в основном джунов и сеньоров. При том что самих вакансий немного, найти работу достаточно легко.
  • Можете сказать, какие скиллы нужны для разработчика на Ruby для джуна, мидла и сеньора?
  • Я бы предпочел сослаться на общепринятые определения. У Ruby нет особой специфики. Джун делает задачи под руководством, мидл может работать самостоятельно, сеньор руководит.
  • Сеньор обычно ставит задачи, но и мидлы могут заниматься постановкой задач. Руководство со стороны сеньора состоит в том, что он определяет, как именно будут сделаны задачи, что они должны затрагивать помимо бизнес скоупа и когда пора заниматься бэклогом. При совмещении с бизнес-процессом сеньор должен выступать скорее экспертом, который помогает тимлиду.
  • Разумеется, в реальности все совершенно не так, и даже джуны являются экспертами в каких то узких областях, а сеньору не стыдно попросить у кого-то помощи в его экспертной области – это просто общая схема. Есть еще стажеры/ньюби/новички. Джуны могут решать задачи любой сложности без руководства, но не очень хорошо. Стажеры все еще учатся этому.
Собственно, тут первое заблуждение с пониманием всего этого. Обычно стажер думает, что стал джуном, когда у него начинает получаться решать свои задачи самостоятельно, но ему пока не ставят очень сложных задач. Джун думает, что становится мидлом, когда ему начинают ставить сложные задачи, и он с ними справляется. Мидл думает, что стал сеньором, когда сеньоры перестают его обильно критиковать. Ну и обычно люди думают, что если они проводят ревью, то они уже сеньоры, хотя я считаю что даже джуны должны принимать участие.

  • У меня есть один знакомый, тоже рубист, кстати, он из стажера перепрыгнул сразу в CTO. Вера в себя есть, нормального понимания того, что нужно от CTO, у работодателя нет, в итоге получаем историю успеха. И в целом он справился. Как говорится, не можешь – научим.
  • Сеньор это должность. Ты можешь быть готов ее занимать, думать что готов ее занимать или ее занимать. Причем то, что ты ее занимаешь, не означает, что ты в принципе готов, но может быть и приятный сюрприз.
  • Сейчас вы на Ruby работаете? Говорят, будто там довольно высокий порог входа. Это правда?
  • В данный момент я уволился с работы (в январе), но продолжаю консультировать бывшую команду и прямо сейчас делаю довольно объемную задачу. Это сложно назвать увольнением даже. Планирую в ближайшее время начать что-то искать, но пока не обновлял резюме.
  • Про высокий порог входа это какой то миф. Я занимаюсь сейчас подготовкой кадров. На знакомство с языком для человека с определенным бэкграундом я отвожу две недели, дальше идет уже знакомство с какими то удобными инструментами и обучение общепринятым практикам. Если брать стажеров с базовым знанием языка, то до уровня джуна они поднимаются за 2 – 4 месяца работы.
  • Фактически вы сейчас занимаетесь обучением?
  • Скорее консалтингом. Обучение занимает у меня несколько часов в неделю. Правильнее даже не консалтинг, а расслабленный фриланс с единственным контрагентом.
  • Чему учите новеньких? Вы учите тех, кто уже что-то знает, или вообще нулевичков?
  • У меня было пока две группы: первая с неоконченным высшим, вторая – просто случайные люди. Совсем с нуля тяжело, плохо понимаю в чем у людей могут быть проблемы. Я познакомился с программированием лет в 8, у меня совершенно другой бэкграунд. Если мы про пару недель на изучение, то это про людей с каким то околоайтишным бэкграундом типа хороших оценок в школе на информатике.
  • Как вы пришли к тому, что стали учить?
  • Учить я начал, потому что мне просто нравится учить людей. Можно учить кого то в интернете жизни, а можно учеников руби. Можно просто помогать с домашкой одноклассникам, тоже обучение. Наверное, примерно в таком порядке и было: сначала чуть чуть помочь подруге с информатикой в школе, потом в универе. Случайно оказавшись в репетиторской тусовке, тоже взял учеников, которые учатся в той же школе и у того же преподавателя, а дальше все как то затихло. Два года назад начал учить сестру с подругами, одна из подруг в итоге работает вместе со мной.
Учить кого то в интернете жизни, кстати, до сих пор нравится больше, хоть и менее продуктивно 🙂

  • Над какими проектами вы работали? Какой из них был самым сложным и интересным?
  • Я работал над gettransfer.com, gettransport.com, wfolio.ru и еще некоторыми проектами. Это не мои проекты, в геттрансфере/транспорте я в принципе был линейным сотрудником. В wfolio.ru – уже сеньором.
Сложными обычно бывают задачи, а не проекты. Самая сложное – это, наверное, промо-акции, которые реагировали на события у пользователей и по каким то настраиваемым правилам выдавали вознаграждение. Но по субъективному ощущению, именно на этой задаче я рос из джуна в мидла.

  • На самом деле это была не одна задача, а много связанных, и не все из них делал я, но я занимался общим рефакторингом архитектуры и потом запиливал большую часть фич, так как кроме меня там мало кто мог разобраться. В целом я воспринимаю это скорее как провал, но я вынес из него много опыта на тему того, как не нужно делать. И было интересно.
  • Из того, с чем сейчас сталкиваюсь, самое сложное – это быстро вникнув в проблему другого человека, объяснить ему решение так, чтобы он мог самостоятельно найти в этом решении несостыковки. Очень мешает авторитет, особенно когда взаимодействуешь с джунами. Тут еще, вероятно, не очень хорошие процессы сказываются: я где-то год хочу попробовать design-review.
Если человек тратит на задачу несколько недель, а ты – пару часов, разумеется, ты не можешь придумать оптимальное решение какой то проблемы. Какой бы у тебя не был опыт, все равно он не переносится дословно.

  • Почему вы решили уйти?
  • Хочется роста, в идеале хочу найти работу, где меня будут учить управлению командой. В принципе, после того как я лучше познакомился с процессом руководства, меня это начало привлекать гораздо больше разработки. Ну и как минимум – разнообразие. Я почти 7 лет пишу код, от этого можно устать.
  • Почему на прежнем месте вы не стали делать карьеру тимлида? Не было возможности?
  • Во-первых, у нас небольшая команда и вряд ли там нужен будет второй тимлид в ближайшем будущем. Во-вторых, это в принципе не так удобно, как расти в большой команде, где тебя могут и научить и подстраховать более опытные лиды.
Говорить о росте сеньора до тимлида в принципе не очень корректно, так как это уже разные направления развития – тут скорее перепрофилирование. Конечно, у сеньора есть набор soft skills, который применим и при работе тимлидом, но на мой взгляд это довольно разные вещи. Сеньор – это эксперт, а тимлид занимается принятием решений. Это разные области.

***

Не все готовы изучать новое сами и покорять вершины так быстро, к тому же опытным специалистам тоже иногда требуется помощь. Идти по пути наименьшего сопротивления и учиться у лучших можно на факультете «Ruby on Rails» образовательной онлайн-платформы GeekBrains. Выпускники курсов получают диплом о профессиональной переподготовке, электронный сертификат и гарантию трудоустройства.

31
Май
2021

❓ Пять причин освоить Ruby и Ruby on Rails в 2021 году

Создателя Ruby вдохновил фантастический роман «Вавилон-17». Получилось ли у Юкихиро Мацумото сделать легкий объектно-ориентированный язык и стоит ли его осваивать сейчас? Попробуем разобраться.

05
Май
2021

Олимпиада Proggy-Buggy Towel Contest 2021

DataArt приглашает всех желающих участвовать в неформальном турнире Международной юмористической блиц-олимпиады по программированию Proggy-Buggy Contest2021
— Читать дальше «Олимпиада Proggy-Buggy Towel Contest 2021»

01
Апр
2021

Опубликован топ-9 самых популярных языков программирования с высокими зарплатами

И для каждого из них указан ожидаемый рост популярности.
— Читать дальше «Опубликован топ-9 самых популярных языков программирования с высокими зарплатами»

16
Дек
2020

🐛 Ловушки безопасности Ruby и как их избежать

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

Перевод публикуется с сокращениями, автор оригинальной статьи Dhruv.

Ruby – универсальный
язык, сочетающий в себе простоту синтаксиса и мощные функции. Благодаря
популярности фреймворка
Rails, Ruby входит в десятку лучших современных языков. Однако с таким комьюнити разработчиков существует множество распространенных
ошибок, ведущих к серьезным последствиям.

Острые ножи


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

«Острые ножи» – это все
доступное в Ruby метапрограммирование, и тот нюанс, что все открыто для
изменения/переопределения в любой момент. Дальше станет понятнее. Рассмотрим
ошибки и их решения.

Небезопасная десериализация

Выполнять все, что
пользователь собирался отправлять – плохая мысль. А вот сериализация/десериализация
пользовательского ввода не кажется такой уж плохой идеей, т. к. никакой код при этом не
выполняется.

Небезопасная десериализация входит в первую десятку OWASP Top Ten чеклиста для веб-безопасности.

Основанная на Psych встроенная библиотека YAML Ruby поддерживает сериализацию пользовательских типов данных в YAML и обратно:

        # serialize.rb
require 'yaml'
require 'set'

s = Set.new([1, 2, 3])
File.open('set.yml', 'w') do |file|
  YAML.dump(s, file)
end
    
        --- !ruby/object:Set
hash:
  1: true
  2: true
  3: true
    

Десериализация этого
YAML возвращает исходный тип данных:

        # deserialize.rb
require 'yaml'
require 'set'

file = File.read('set.yml')
s = YAML.load(file)
p s
    
        $ ruby deserialize.rb

#<Set: {1, 2, 3}>
    

Как вы можете видеть,
строка -- !ruby/object:
Set
описывает, как повторно создавать экземпляры объектов из их текстовых
представлений. Это открывает множество векторов атаки, которые могут перерасти
в RCE.

Решение

Решение заключается в
использовании безопасной загрузки. Используйте функцию YAML::safe_load вместо
YAML::load. Она полностью блокирует загрузку пользовательских классов:

        # deserialize.rb
require 'yaml'
require 'set'

file = File.read('set.yml')
s = YAML.safe_load(file)
p s
    
        $ ruby deserialize.rb

/usr/ruby/2.7.0/psych/class_loader.rb:97:in `find':
Tried to load unspecified class: Set (Psych::DisallowedClass)
    

Стандартные типы вроде хэшей и массивов все еще могут быть сериализованы в документы YAML и
десериализованы из них, как и раньше.

        ---
hash:
  1: true
  2: true
  3: true
    
        $ ruby deserialize.rb

{"hash"=>{1=>true, 2=>true, 3=>true}}
    

IO hijacking


Если вашему приложению
необходимо читать или записывать пользовательские файлы с диска или делать
запросы через API к пользовательским URL-адресам, вы можете написать следующий код:

        # test.rb
puts 'Enter file path:'
path = gets.chomp
puts 'File contents:'
open(path, 'r') do |file|
  until file.eof? do
    puts file.gets
  end
end
    

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

Функция Kernel::open из приведенного выше фрагмента кода имеет еще одну
дополнительную функцию, которая используется для порождения процессов. Посмотрите,
что происходит, когда вы передаете
начинающиеся с символа конвейера ( | ) входные данные:

        $ ruby test.rb

Enter file path:
|date
File contents:
Sun Nov 15 22:03:33 IST 2020
    

Она выполняет команду
date и передает выходные данные обратно Ruby. Злоумышленник будет выполнять
команды гораздо более разрушительные, чем в этом коде. В нашем примере базовое
RCE – удаленный пользователь, выполняющий код на сервере с полными
привилегиями, доступными вашему веб-приложению.

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

Решение

Никогда не используйте
Kernel::open! Альтернативой является File::open, URL::open или
IO::open, в зависимости от контекста. Попробуем еще раз, на этот раз с
File::open вместо Kernel::open. Такой вариант гораздо более безопасен, поскольку он не дает доступа к shell:

        # test.rb
puts 'Enter file path:'
path = gets.chomp
puts 'File contents:'
File.open(path, 'r') do |file|
  until file.eof? do
    puts file.gets
  end
end
    
        $ ruby test.rb

Enter file path: 
|date
File contents:
Traceback (most recent call last):
	2: from test.rb:4:in `<main>'
	1: from test.rb:4:in `open'
test.rb:4:in `initialize': No such file or directory @ rb_sysopen - |date (Errno::ENOENT)
    

SQL injection


Инъекция происходит,
когда пользовательский ввод из фронтенда без проверок и очистки применяется непосредственно
в SQL-запросе на бекенде.

Допустим, у вас есть
столбец
users, в котором выполняется
поиск по
введенному в форму имени. Вот, как бы это выглядело в Ruby:

        User.where("name = '#{name}'")
    

Это небезопасно.
Рассмотрим следующий ввод от злоумышленника:

        name = " ' OR '1' = '1" # Ввод от злоумышленника
    

Запрос ложный, как видно
в первой строке и крашится из-за вредоносного кода, как показано во второй
строке. WHERE всегда
true и возвращает
каждого пользователя из таблицы:

        SELECT * FROM users WHERE name = '<name>'         -- <name> ложный запрос
SELECT * FROM users WHERE name = ' ' OR '1' = '1' -- все сломалось
    

Решение

Используйте один из следующих
двух способов:

        User.where(["name = ?", name])
User.where({ name: name })
    

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

Автоинкремент ID

Когда вы создаете
модель Rails, автоматически создается id – автоинкрементное целочисленное
поле. По большей части этого достаточно. Целочисленные идентификаторы
имеют преимущество: поскольку они постоянно увеличиваются, нет никаких шансов
на коллизию. Что произойдет, если пострадает безопасность:

  • Масштабирование может стать сложнее. Если множество серверов работают независимо друг от друга, вполне вероятно, что они могут назначить один и тот же ID разным ресурсам.
  • Станет возможным определить, сколько у вас объектов. Можно зарегистрироваться и увидеть собственный идентификатор, чтобы узнать количество клиентов и даже оценить бизнес-показатели.
  • Можно будет перебирать и красть данные. Злоумышленник сможет вывести весь список и получить все ограниченные ресурсы.
  • Возможна утечка конфиденциальной информации. Незарегистрированные ресурсы, видимые только держателям ссылок, сломались бы из-за целочисленных ID.

Решение

Используйте UUID. С Rails
сделать это будет очень просто. После несложного изменения все ваши модели будут использовать UUID в качестве первичных ключей:

        # config/application.rb 
config.generators do |g|
  g.orm :active_record, primary_key_type: :uuid
end
    

Если вы все-таки хотите
использовать целые числа, берите большие, выбранные случайным образом. Посмотрим
на структуру URL-адресов ролика из YouTube. Так выглядит его URL-адрес:

        https://www.youtube.com/watch?v=dQw4w9WgXcQ
    

Идентификатор видео – это
случайное число между $0$ и $64^{11}$ (более 73 квинтиллионов чисел), закодированное
в Base64. Не совсем UUID, но и не целочисленное поле с автоинкрементом.

Инструменты в помощь

Ключевой вывод из описанных выше примеров – никогда не доверять юзеру. Данные пользователя не
должны быть напрямую сериализованы/десериализованы, оценены или обработаны. В
качестве дополнительных мер предосторожности подойдет специальный софт.

Статические анализаторы кода


Инструменты анализа
кода, такие как линтеры и сканеры уязвимостей, могут найти множество просчетов
до того, как те начнут эксплуатироваться.
RuboCop уведомит вас о проблемах безопасности, вроде небезопасной десериализации или IO
hijacking, а также предложит варианты исправления.

Brakeman
– сканер уязвимостей, который может найти SQL-инъекцию среди других ошибок
безопасности. Оба инструмента являются бесплатными и поставляются с открытыми исходными текстами.

DeepSource – комплексное ПО, способное сканировать код, на каждом коммите, анализировать результаты работы линтеров/анализаторов
и автоматически устранять множество проблем.

Для большинства языков программирования это решение имеет собственные
пользовательские анализаторы, которые постоянно совершенствуются
и обновляются. А еще оно элементарно устанавливается – нужно всего лишь
добавить .deepsource.toml файл в корень репозитория и DeepSource готов:

        version = 1

[[analyzers]]
name = "ruby"
enabled = true

[[transformers]]
name = "rubocop"
enabled = true
    

Заключение

Проблемы с безопасностью
– самые опасные и дорогостоящие. Будьте предельно внимательны и учитывайте все
вышесказанное в своих проектах. Обязательно продолжайте изучать язык программирования, ошибки других разработчиков и нашу статью про
ошибки новичков. Удачи!

16
Дек
2020

Третий раунд битвы языков программирования 2020!

По итогам вчерашнего раунда С++ буквально уничтожил Cobol, а Assembler оказался почти в два раза популярнее чем Pascal. Результаты смотрите здесь. Сегодня у нас новые соперники: SQL/TypeScript и Python/Ruby. Вы
— Читать дальше «Третий раунд битвы язык…

13
Дек
2020

Примите участие в баттле языков программирования 2020. Старт уже завтра!

В то время как Java и язык Си меняются местами на вершине рейтинга TIOBE, мы решили выяснить, какие языки программирования, наши подписчики любят больше всего. Завтра начинается баттл языков программирования
— Читать дальше «Примите участие в баттле я…

19
Ноя
2020

Как связать переменную в js файле c контроллером

Делаю интерактивную карту, есть база данных кабинетов с координатами и этажами, где кабинеты расположены, этажи переключаются посредством кнопок, для каждого этажа своя кнопка. Как передавать переменную зависящую от кнопки в контроллер, чт…

17
Окт
2020

Международная олимпиада по программированию Proggy-Buggy Contest 2020

Олимпиада пройдёт в весёлой атмосфере и предназначена для всех энтузиастов программирования: учеников, студентов, тестировщиков и других.
— Читать дальше «Международная олимпиада по программированию Proggy-Buggy Contest 2020»

13
Сен
2020

Ошибка при обработке AJAX запроса сервером ruby

У меня есть AJAX запрос, который взаимодействует с сервером написанным на ruby. Когда я делаю запрос с браузера сервер кидает ошибку.
127.0.0.1 – – [13/Sep/2020:14:59:38 -0400] "OPTIONS / HTTP/1.1" 404 462 0.0021

Когда я делал з…

12
Сен
2020

Как пропарсить http запрос на ruby сервере?

Я делаю ajax запрос на свой сервер на сервер. Получить запрос я могу, ответ с сервера также идет. Но я не могу получить данные, которые я передаю по запросу. Как мне реализовать читание данных?
Мой запрос
$.ajax({
url: ‘http://127.0.0.1:56…

11
Июн
2020

18–19 июля, онлайн: конференция RubyConfBY 2020 Online

Ежегодная конференция, посвящённая Ruby, Rails и сопутствующим технологиям, впервые пройдёт в онлайн-формате и разделена на два дня.
— Читать дальше «Конференция RubyConfBY 2020 Online»

09
Июн
2020

18 июня, онлайн: Online Ruby Meetup №12

Поговорят про проблемы с производительностью Ruby-приложений, как писать простой и поддерживаемый код, CQRS-паттерне и использовании PostgreSQL в проектах.
— Читать дальше «Online Ruby Meetup №12»

22
Май
2020

Исполнение кода python в ruby без файла

Есть бд с разными фрагментами кода, из них динамически с помощью ruby генерируется python код, в итоге мы получаем строку с python кодом, который нужно исполнить. Как можно это сделать, не создавая файл?

21
Апр
2020

10–30 апреля, онлайн: курсы ProGate

Онлайн-платформа Progate открыла доступ к 15 коротким онлайн-курсам для новичков. Можно изучить Python, Java, PHP, SQL, HTML, jQuery, Ruby и Ruby on Rails.
— Читать дальше «Онлайн-курсы ProGate»

07
Фев
2020

Минишеллы для решения повседневных задач

Уже давно и успешно использую miniperl в своей работе. Совсем недавно после сборки ruby обнаружил miniruby, – тоже удобная вещь, способная заменить собой с десяток-другой утилит. А есть ли аналоги у python, lua, node или какого другого инт…

09
Сен
2019

13 сентября, Санкт-Петербург: олимпиада Proggy-Buggy

Международная олимпиада для тех, кто владеет любым из следующих языков программирования: C++, Free Pascal, Java, C#, Python, Ruby, PHP, JavaScript.
— Читать дальше «Олимпиада по программированию Proggy-Buggy»

27
Мар
2019

Конференция RubyConfBY 2019

Рубисты из разных стран обсудят последние новости, обменяются опытом и поделятся необычными техниками. Среди участников в этом году — создатель Nokogiri.
— Читать дальше «Конференция RubyConfBY 2019»

04
Фев
2019

Митап Winter SaintP Ruby

16 февраля в Санкт-Петербурге пройдёт митап локального сообщества Ruby-программистов. Кого ждут? Всех, кому не безразличен Ruby и интересна разработка на этом языке. О чём пойдёт разговор? На встрече выступят профессионалы сферы с докладами на серьёзны…

05
Сен
2018

Конференция EPAM Software Engineering Conference

22 сентября в Минске состоится SEC — Software Engineering Conference от компании EPAM. Мероприятие впервые открыто для внешних участников. Что это? Это более 3 000 участников, 90 спикеров и 500 представителей экспертных сообществ. Последним отведены 2 …