Задать вопрос
Gamedev, Webdev
C#, Javascript, PHP
Также преподаю программирование в колледже.
Контакты

Достижения

Все достижения (19)

Наибольший вклад в теги

Все теги (115)

Лучшие ответы пользователя

Все ответы (334)
  • Что изучать, на что тратить свободное время, чтобы в будущем стать востребованным программистом с нормальным заработком?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Ответ на вопрос будет сильно зависеть от того, в каком направлении вы думаете развиваться.
    Будет ли это сетевое программирование? Тогда это си, в основном.
    Может быть, веб-программирование? Тогда тут могут быть php, javascript, python, ruby.
    Захотите разрабатывать программы на десктоп? Вам нужны c# или java.
    На мобильные платформы? тогда java и objective c (плюс swift).
    Или податься в разработку игр? Тогда либо c++, либо с# (для Юнити - наверное, самой популярной платформе).
    Хотите экзотики? Приглядитесь к функциональным языкам - Erlang и Haskell.
    Разработка железа и драйверов для железа? тогда си (без плюсов) и ассемблер.
    Определитесь, что вы хотите, потому что всё объять не получится. Выберите один (или два) направления и добейтесь хорошего уровня в нём. А потом вам будет уже легче двигаться дальше.

    Мой совет - попробуйте изучать C# или Java (они во многом похожи) для софта, или Javascript и php/python для веб-приложений и сайтов.

    Добавлю, что очень правильный совет дал @tsarevfs - помимо языка программирования, хороший программист должен знать несколько инструментов - и в первую очередь, это система контроля версий, например, git. Плюс юнит-тестирование (хотя это можно начать изучать позже, через годик-два). Плюс - нужно хорошо знать свою IDE, в которой работаете; не вздумайте работать в блокнотиках!

    Ещё помимо практики нужно знать теорию - читайте Макконнелла, Фаулера, Мартина, Бека.
    Подпишитесь на хабре на пару десятков хабов и регулярно читайте всё подряд. Через годик ваш уровень понимания статей сильно вырастет.

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

    UPD. Важное дополнение из обсуждения в комментариях (спасибо @Argentum88 @Deerenaros )
    Чтобы стать профессионалом и "востребованным программистом с нормальным заработком", нужно очень хорошо понимать внутреннее устройство тех систем (платформ, фреймворков), на которых идёт работа.
    Для этого нужно заглядывать вглубь. Изучив различные мейнстрим-инструменты, посмотреть на аналогичные менее популярные системы. Изучать исходный код используемых open-source библиотек. Написать свою подобную систему. Для web - написать свою CMS (хотя бы базовую). Для десктоп-программ - попробовать программировать без навороченных библиотек, которые делают рутинную работу за программиста. Для разработчика игр - сделать простую игру на базовом инструментарии платформы, где всё придётся делать своими руками.
    Всё это даст возможность проникнуться, почему всё делается именно так, даст понимание взаимосвязей разных частей программы.
    А потом, осознав это, выбрать один из уже готовых инструментов, и продолжать писать на нём, уже обладая более глубоким его пониманием.
    Ответ написан
    21 комментарий
  • Как научится верстать из PSD макетов в html+css?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Посмотрите вот эти две статьи с хабра:
    Как сверстать веб-страницу. Часть 1
    Как сверстать веб-страницу. Часть 2 — Bootstrap
    И прочтите все комментарии к этим статьям (впрочем, как обычно на хабре:)
    Очень хорошие статьи, пошагово расскажут, что делать с макетом.
    UPD. Ещё одна статья от того же автора:
    Как сверстать тему для WordPress
    Ответ написан
    Комментировать
  • В двух словах, что такое БЭМ?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    БЭМ - это такая методология вёрстки от Яндекса. Она подразумевает разбиение страниц на отдельные смысловые блоки (комментарий, пост, заголовок, футер, форма, инпут и т.п.). Каждый блок может состоять из других блоков. Основная идея - как можно больше повысить возможность повторного использования уже написанных блоков, для чего используются модификаторы. Плюс, БЭМ подразумевает отказ от каскадных стилей, потому что они препятствуют повторному использованию.
    Например, на странице есть два разных заголовка (например, отдельно в статье, и отдельно во врезке). Как все привыкли делать это? есть код заголовка:
    <h1 class="header">Заголовок</h1>
    И мы ставим эти заголовки в текст статьи и во врезки:
    <article class="article">
        <h1 class="header">Заголовок</h1>
        <p>Текст текст текст</p>
    </article>
    <aside class="incut">
        <h1 class="header">Заголовок</h1>
        <p>Текст текст текст</p>
    </aside>

    Тогда обычно мы используем каскад, чтобы стилизовать заголовок во врезке:
    .header {font-size: 2em; padding-bottom: 1.5em;}
    .incut .header {text-decoration: italic;}

    Всё хорошо, но теперь мы не можем просто перенести эти стили заголовка во врезке в другое место, потому что эти стили привязаны именно ко врезке (классу incut). Плюс, что ещё хуже, если к элементу привязано несколько различных стилей, образующихся подобными каскадными правилами, то перенести такой внешний вид в другое место становится очень трудоёмко. А также, из-за большей специфичности каскадных стилей, их сложнее "перебить" новым стилем.
    БЭМ предлагает отказаться от каскадных стилей и создавать отдельные стили-модификаторы:
    <article class="b-article">
        <h1 class="b-article__header">Заголовок</h1>
        <p>Текст текст текст</p>
    </article>
    <aside class="b-article b-article__incut">
        <h1 class="b-article__header b-article__header_incut">Заголовок</h1>
        <p>Текст текст текст</p>
    </aside>


    .b-article__header {font-size: 2em; padding-bottom: 1.5em;}
    .b-article__header_incut {text-decoration: italic;}


    Чем больше проект, тем выгоднее использование подобной методологии. На маленьких и средних проектах БЭМ может быть избыточен. Хотя вот была статья habrahabr.ru/company/yandex/blog/234905 про использование в маленьких проектах.

    БЭМ может использоваться самостоятельно, вручную создавая все элементы и блоки. Но существует обширный инструментарий для БЭМа, который помогает создавать библиотеку элементов и блоков.

    Ну вот. Получилось не в двух словах, но менее подробно качественно описать БЭМ не получится, имхо.
    Ответ написан
    Комментировать
  • Как заменить switch case паттерном стратегия?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Switch
    public enum DamageType { Melee, Range, Magic }
    public class Monster
    {
        public double Health { get; private set; }
        public double MeleeDamage { get; private set; }
        public double RangeDamage { get; private set; }
        public double MagicDamage { get; private set; }
        public DamageType FavoriteDamageType { get; private set; }
    
        public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, DamageType favoriteDamageType)
        {
            Health = health;
            MeleeDamage = meleeDamage;
            RangeDamage = rangeDamage;
            MagicDamage = magicDamage;
            FavoriteDamageType = favoriteDamageType;
        }
    
        public void AttackTo(Monster monster, DamageType damageType)
        {
            switch (damageType) // используется switch
            {
                case MonsterType.Melee: monster.Health -= MeleeDamage; break;
                case MonsterType.Range: monster.Health -= RangeDamage; break;
                case MonsterType.Magic: monster.Health -= MagicDamage; break;
            }
        }
    
        public void AttackTo(Monster monster)
        {
            AttackTo(monster, FavoriteDamageType);
        }
    }


    То же самое, но со стратегией
    public class Monster
    {
        public double Health { get; set; }
        public double MeleeDamage { get; private set; }
        public double RangeDamage { get; private set; }
        public double MagicDamage { get; private set; }
        public IDamageStrategy FavoriteDamageStrategy { get; private set; }
    
        public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, IDamageStrategy favoriteDamageStrategy)
        {
            Health = health;
            MeleeDamage = meleeDamage;
            RangeDamage = rangeDamage;
            MagicDamage = magicDamage;
            FavoriteDamageStrategy = favoriteDamageStrategy;
        }
    
        public void AttackTo(Monster monster, IDamageStrategy damageStrategy)
        {
            damageStrategy.Attack(this, monster); // не используется switch
        }
    
        public void AttackTo(Monster monster)
        {
            AttackTo(monster, FavoriteDamageStrategy);
        }
    }
    
    
    public interface IDamageStrategy
    {
        void Attack(Monster attacker, Monster defender);
    }
    public class MeleeDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.MeleeDamage;
        }
    }
    public class RangeDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.RangeDamage;
        }
    }
    public class MagicDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.MagicDamage;
        }
    }

    Отличие класса Monster только в коде первого метода AttackTo. Ну и свойства FavoriteDamageType или FavoriteDamageStrategy.

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

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Полиморфизм указывает, какую версию метода текущего объекта запустить.
    Например, у вас есть несколько наследуемых классов, с разной реализацией одного и того же метода. То есть, у вас есть несколько разных методов с одинаковым именем (и сигнатурой), реализованных в разных классах. Какую версию метода вызвать? Это зависит от типа переменной, в которой находится объект.
    Также с помощью полиморфизма можно поместить объекты разных классов в один массив с типом базового класса.

    Создадим три класса с двумя методами - один виртуальный, а другой нет. Виртуальный метод переопределён (override) в классах-наследниках. Невиртуальный метод просто скрыт в наследниках новой реализацией (невиртуальные нельзя переопределять).
    class Animal {
        public void Info() { Console.WriteLine("Animal"); }
        public virtual void Say() { Console.WriteLine("Nothing to say"); }
    }
        
    class Cat : Animal {
        public void Info() { Console.WriteLine("Cat"); }
        public override void Say() { Console.WriteLine("Meow"); }
    }
        
    class Dog : Animal {
        public void Info() { Console.WriteLine("Dog"); }
        public override void Say() { Console.WriteLine("Woof"); }
    }

    При создании объекта важно, в переменную какого типа объект будет записан:
    Dog dog1 = new Dog();
    Animal dog2 = new Dog();
    // Не виртуальный метод - вызовется метод класса, указанного у переменной 
    dog1.Info(); // напишет Dog
    dog2.Info(); // напишет Animal
    // Виртуальный метод - вызовется метод класса, которого переменная реально имеет
    dog1.Say(); // напишет Woof
    dog2.Say(); // напишет Woof


    А теперь частая ситуация, когда полиморфизм нужен - при итерации массива:
    Animal[] animals = new Animal[10];
    FillAnimals(animals); // заполним массив вперемешку собаками и кошками
    
    foreach (var animal in animals) animal.Say(); // вызовется правильный метод
    // У невиртуальных методов так сделать нельзя! Полиморфизм в действии

    Наследование без виртуальных методов полезен только фиксацией интерфейса.

    Вот весь код примера: code.re/5ZC
    Вставьте его вот сюда и проверьте.

    P.S. Написал код на C#, чтобы подчеркнуть разницу между виртуальными и невиртуальными методами. В Javascript все методы виртуальные (как и в php, например).

    UPD. (спасибо @Petroveg)
    В языке C# (и других статически типизированных) обычно делают так - если метод в базовом классе записывается для всех потомков и оттуда будут использоваться напрямую, то он помечается обычным, невиртуальным. А если метод предназначен для того, чтобы в наследниках его переопределить, то необходимо его сделать виртуальным, чтобы при вызове метода компилятор выбрал нужную версию метода. То есть некоторые методы лучше делать виртуальными, а некоторые нет.
    И ещё раз - виртуальность важна только в одном случае - если объект-наследник записан в переменную базового класса:
    Animal animal = new Dog();
    В javascript невиртуальных методов не бывает - динамическая основа этого языка ВСЕГДА автоматически вызывает именно последнюю версию метода, определяя конкретную по цепочке прототипов. Поэтому в Javascipt, по большому счёту, сильно думать о полиморфизме смысла нет - это только абстрактная концепция, не влияющая на сам код, а только на архитектуру.
    Ответ написан
    6 комментариев

Лучшие вопросы пользователя

Все вопросы (20)