• Почему последнее время в Разработке такие маленькие зарплаты?

    php666
    @php666
    PHP-макака
    Crash попросил меня как "эксперта" высказаться, я не эксперт, но мнение есть.

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

    Это не реальность плохая, реальность как была, таковой и осталась. Это ваши воздушные замки рушатся об реалии. Поймите уже, наконец, если и есть в айти зарплаты, сопоставимые с зп депутата госдумы, то 99% программистишек они не светят. Как правило, это люди пишущие на низкоуровневых языках типа С и опытом в 10+ лет.

    На приведенном скриншоте зп до 90 тр за знания хтмл-цсс-пхп, ничего сверхъестественного, обычная зарплата для озвученного уровня. С чего ты решил, что достоин получать 150 или 200 за подобный стек требований?

    хотелось бы услышать мнение разработчиков с опытом что он думают на этот счет
    Ок. Слушай сюда. Эта сфера - полное гавно. Как по деньгам, так и по перспективам.

    Кодить после 35 - жуткий ад.
    Знания улетучиваются, требования в вакансиях мутируют и/или растут. Мы не успели закончить проект на фреймворке версии 6, уже вышла версия 8. И так без конца. Не изучил новый фреймворк - летишь на мороз. Не знаешь современные технологии (не изучал их в своё свободное время) - летишь на мороз.

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

    когда паралельно, в других сферах строительства , полиции , армии, и тд, зарплата без опыта ближе, а то и выше этих значений
    тоже верно. Но знаешь, в чем прикол? Любой айтишник, поработавший в айти и успевший "повзрослеть" в рамках этой работы, уже НИКОГДА не попадет ни в полицию, ни в строительство. Допустим я - мне 38 долбанных лет и я в айти всю жизнь. Мне деваться некуда. Меня никто не возьмет, возраст под сорок, перспективы все закрыты. В полицаи или в стройку надо идти в 20+ лет. Так что и тут кроется западня - человек без должного ментовского или строительного образования, в возрасте и без соответствующего бэкграунда даже там никому нах не нужен будет.

    Так что профессию надо по уму выбирать, а не по сплетням из интернета.
    Ответ написан
    5 комментариев
  • Почему последнее время в Разработке такие маленькие зарплаты?

    Zoominger
    @Zoominger
    System Integrator
    Лол, а что вы хотели-то?

    Вместо людей, пришедших в IT по призванию и добившихся успеха многолетним тяжким трудом, подкреплённым истинным фанатизмом и любовью к своему труду (это я про себя, да), в сферу ломанулось стадо откровенно глупеньких и недалёких вайтишников, которые насосались пропаганды от курсоводов про "триста тыщ на удалёнки на пехепе нинапригаясь", причём оглянитесь - этих балбесиков даже не переубедить, они свято верят, что в IT деньги раздают просто так и что веб - это лежать под пальмами с Макпуком и пить коктейли, которые подносят мулатки. По факту же вместо Мальдив - хрущёвка, вместо Макпука - убогий Хлаоми, а вместо мулаток и коктейлей - мамка с чаем из пакетика.

    И да:
    условно говоря юниор средняя около 30-40к

    15-20k. Рублей. В мегаполисе. В галере с полной загрузкой.
    Ответ написан
    6 комментариев
  • В каких случаях использовать приватные поля при определении класса?

    HemulGM
    @HemulGM
    Delphi Developer, сис. админ
    Вы здесь почти ничего осмысленного из ООП не используете. Пишу пример на паскале, но это ничего не меняет.

    Стандартным решением было бы создать базовый класс "Рисуемый", тот, который может быть отрисован на канве.
    Допустим TSprite. И объявим виртуальный метод Draw, чтобы мы могли попросить отрисываться.
    TSprite = class //ну или интерфейс
    public
      procedure Draw; virtual; abstract;
    end;

    Теперь напишем класс TRectangle на основе класса TSprite. Где тоже объявим метод Draw, но напишем там уже отрисовку. Ну и объявим приватные поля размеров и позиции с конструктором.
    TRectangle = class(TSprite)
    private
      FX, FY, FH, FW: Float;
      FCanvas: TCanvas;
    public
      procedure Draw; override;
      constructor Create(Canvas: TCanvas; const X, Y, H, W: Float); 
    end;
    
    constructor TRectangle.Create(Canvas: TCanvas; const X, Y, H, W: Float); 
    begin
      FCanvas := Canvas;
      FX := X;
      FY := Y;
      FH := H;
      FW := W;
    end;
    
    procedure TRectangle.Draw;
    begin
      FCanvas.Rectangle(FX, FY, FH, FW); // Это отрисовка фигуры на канве
    end;


    Теперь мы можем создавать класс TRectangle, указывать целевую канву и размеры.
    Rect := TRectangle.Create(Canvas, 10, 10, 40, 45);
    Rect.Draw; // Всё, можно отрисовать


    После всего этого мы можем создать другие фигуры или объекты, которые тоже будут наследоваться от TSprite. Сможем поместить их в список объектов типа TSprite и обращаться к каждому объекту через Draw. Например, в цикле отрисовки всех объектов.
    Ответ написан
    3 комментария
  • В каких случаях использовать приватные поля при определении класса?

    sarapinit
    @sarapinit
    Точу водой камень
    если у вас typescript, вы можете так сделать

    class Rectangle {
      readonly x: number
      readonly y: number
      readonly w: number
      readonly h: number
        
      constructor(x: number, y: number, w: number, h: number) {
        this.x = x
        this.y = y
        this.w = w
        this.h = h
      }
    }
    
    class Canvas {
      private w: number
      private h: number
    
      constructor(w: number, h: number) {
        this.w = w;
        this.h = h;
      }	
    
      public drawRect(rect: Rectangle) {
        //draw implementation
      }
    }


    В этом случае Rectangle просто контейнер для чисел и никто его менять не может. Но поля публичные и то позволяет его отрисовать.
    Но это решение справедливо только для этого случая. В целом вопрос более глубокий и не имеет единого ответа.

    Рекомендую почитать про Rich model и Anaemic model, это даст некоторое понимание про разницу подходов и то какие плюсы\минусы есть.
    Ответ написан
    2 комментария
  • Как нужно искать open source проекты для дальнейшего участия в них?

    Глупо искать проект по языку или популярности просто ради ачивки "я внёс вклад в ненужный мне проект".

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

    Оглянитесь вокруг, посмотрите на программы которые вы используете повседневно. Какие из них открытые? Что вас и не только вас в них раздражает? Посмотрите в багтрекер. И вперёд.
    И тогда свой вклад вы будете видеть ежедневно.
    Ответ написан
    Комментировать
  • Как нужно искать open source проекты для дальнейшего участия в них?

    neuotq
    @neuotq
    Прокрастинация
    Лично я советую два источника:
    https://www.codetriage.com/ - специальный сервис который позволяет удобно структурировать опенсурс проекты по issue и языкам, и выбрать для начала работы.
    https://cultofmartians.com/ - интересный проект, приглашение к участию от одной из самых крутых команд в рунете. Ставят задачи, потом есть шанс и подружится с ними ближе.
    Ответ написан
    Комментировать
  • Каким браузером можно заменить chrome?

    Zoominger
    @Zoominger
    System Integrator
    Смотрю в сторону оперы

    Это тот же Хром, просто с другим оформлением.
    Firefox пойдёт.
    Ответ написан
    2 комментария
  • Как вы учите новое?

    Очень просто, придумываете свой пет-проект, декомпозируете задачи и решаете их, гугля и ища ответы на свои вопросы.

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

    Главное — продумайте основной функционал, который хотите сделать, заранее. Например в случае с todo нужно добавлять / удалять / редактировать, чтобы можно было остановится и понимать, что задача закончена.

    И, конечно же, интереснее всего решать свои посведневные задачи, пытаться что-то автоматизировать. Не потеряете интерес и прокачаете навыки.
    Ответ написан
    Комментировать
  • Как вы учите новое?

    verkhoturov
    @verkhoturov
    Frontend Developer
    Придумываешь пет-проект, делаешь, тупишь, гуглишь как надо делать, снова делаешь, снова тупишь, гуглишь...
    Ответ написан
    2 комментария
  • Стоит ли переписывать полностью метод в данной ситуации?

    @vista1x
    Сделайте общий метод getUsersQuery(), который просто возвращает пользователей без какой либо сортировки. Свой метод getUsers() измените так, что бы он использовал первый метод. Плюс, добавьте метод getUsersSorted(), где будете возвращать данные, отсортированные в нужном виде. Не зная структуры проекта сложно написать какие то примеры кода, но я бы сделал примерно так:

    function getUsersQuery() {
        // ...
    }
    function getUsers() {
        return getUsersQuery()->orderBy('id');
    }
    function getUsersSorted() {
        return getUsersQuery()->orderBy('name');
    }
    Ответ написан
    Комментировать
  • Можно ли делать редиректы из моделей?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Нельзя.

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

    В данном случае тут же станет ясно, что редирект в командной строке - а следовательно и в модели - является бессмыслицей. А любые манипуляции с НТТР протоколом должны совершаться в том единственном компоненте, который отвечает за работу c HTTP - контроллере.
    Ответ написан
    Комментировать
  • Как не нарушать SOLID?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вы путаете инверсию контроля и инверсию зависимости. Давайте по порядку кратенько.

    Зачем нам нужны контроллеры или различные представления данных

    Зачем нам в принципе контроллер? Что он делает? Для упрощения не будет воспринимать контроллер как "один объект" и вместо этого представим себе его как целый слой. Так же заменим слово "модель" словом "приложение".

    Задача контроллера - принять и обработать запрос и выдать ответ. По сути в контексте WEB наш HTTP запрос и ответ это представление, которое хочет получить клиент (браузер, мобильное приложение, SPA, что угодно). HTTP - это интерфейс пользователя (UI) для нашего web-приложения.

    Например что бы независеть от реализации клиента и что бы было удобно мы передаем даты в формате iso 8601 (пример: 2016-07-14T19:40:12Z). Это удобно что бы быть независимым от реализации клиента или сервера. Но это не удобно для нашего приложения. В приложении скорее всего нам удобнее всего работать с объектом типа DateTime. То есть приложение использует абсолютно другое представление.

    Мы могли бы прямо в приложении конвертить DateTime в iso 8601 но тогда мы делаем наше приложение привязанным к одному конкретному представлению, которое хочет получить клиент. К примеру по каким-нибудь причинам известным только темным богам, вам вдруг понадобится быстро прикрутить интеграцию с другим сервисом и те же данные гонять уже в RFC2822. И стало быть уже приложению нужно париться о еще одном представлении.

    Мы могли бы сделать какие-то адаптеры у приложения, и дергать их в зависимости от потребностей, но тогда опять же наше приложение все еще знает о представлении, которое ему собственно не нужно. То есть у нас есть зависимость приложения от его UI что... похоже на "не лучшую идею". И тут на помощь приходит Inversion of Control.

    Что такое Inversion of Control

    Тут название само говорит за себя. Допустим у нас был объект A который дергал объект B, причем объект A по сути и не должен ничего знать об объекте B потому то это не его дело. Принцип инверсии контроля говорит нам о том, что в таких ситуациях именно B должно вызывать A, таким образом меняя направление потока управления. Это позволяет нам уменьшить связанность и повысить зацепление компонентов нашей системы. Так же сделав это у нас может появиться объект C который так же будет дергать объект A. Если говорить о UI - мы просто можем сделать несколько реализаций UI.

    То есть если еще упростить - фреймворк должен дергать ваш код, а не код дергать код фреймворка. Тем самым мы снижаем связанность одного от другого.

    Роутер и контроллеры как реализация UI

    Что бы отвязать приложение от логики формирования представления, вынесем это все в отдельный "слой" и назовем этот слой - контроллеры. Точнее это будет как цепочка адаптеров. Один адаптер (фронт-контроллер по сути) получает Request и делает какие-нибудь вещи с ним. Например проверяет можем ли мы вообще делать подобный запрос. Другой адаптер вызывает роутер и выясняет какой дальше адаптер вызвать. Если следующий адаптер не вызван - надо вернуть 404-ую ошибку. Если же все пошло хорошо - мы вызываем еще один адаптер, который уже будет конвертировать HTTP запрос в какое-то действие приложения (вызов метода приложения по сути).

    Так а инверсия зависимости это что?

    Инверсия зависимости - очень похожа на инверсию контроля но действует чуть по другому. Проще всего будет вглянуть на картинку:

    Dependency_inversion.png

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

    Если мы не хотим завязываться на SwiftMailer, и дать возможность в будущем изменить способ отправки почты, мы можем в рамках нашего модуля объявить интерфейс а в другом модуле уже его реализовать с применением SwiftMailer. Для упрощение под модулями мы можем понимать неймспейсы например.

    Нужно ли соблюдать принцип инверсии зависимости в случае контроллеров?

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

    будет ли правильным передавать зависимости в роутинге

    Это уже вопрос реализации IoC. Конкретно вы хотите получить что-то вроде Dependency Injection. Вы можете забрать зависимости из аргументов метода экшена. или аргументов конструктора контроллера.... или просто использовать контейнер зависимостей внутри контроллера.... это совершенно не важно. Контроллеры это то место где высокая связанность на компоненты фреймворка более чем допустимы.

    С другой стороны у вас теперь роутинг совмещает обязанность маршрутизации и разруливания зависимостей. Сами понимаете что это как-то нарушает прицип единой ответственности. Этим может заниматься Controller Resolver какой-нибудь.
    Ответ написан
    2 комментария
  • В каком классе писать логику столкновений двух объектов?

    hack504
    @hack504
    Нигде. В парадигме ООП и снежинка и варежка и сцена - описывают только свое поведение методами и свойствами. Введите ещё одну абстракцию - мир(или физика), которая содержит все эти объекты и описывает поведение их взаимодействия.
    Сцена детектит столкновение снежинкой и варяжкой - передает миру, а тот в свою очередь удаляет снежинку, запускает анимацию варяжке, запускает в сцене радостный звуковой щелчок.
    Таким образом, если в дальнейшем реализовывать дополнение "Грачи прилетели", то легко реализуется логика столкновения варяжки и помета => помёт остается, варяжка замирает, в сцене грустный звук "ооу"
    Ответ написан
    Комментировать
  • Как классифицировать новость с помощью машинного обучения?

    @dmshar
    Меня всегда интересовало - люди начинают заниматься такими вопросами из соображений простого любопытства или им дают такое задание по работе? Если первое - то почему сразу за советами в форум, а не элементарный поиск в интернет или чтение учебника. Если второе - то почему не объяснить работодателю, что вы не специалист в теме?
    А информации не самом деле уйма - книги, веб ресурсы, курсов, любой учебник по машинному обучению содержит соответствующий раздел или как минимум пример.

    https://www.slideshare.net/compscicenter/-32801202
    https://www.youtube.com/watch?v=hULD4jS5DEc
    https://towardsdatascience.com/text-classification...
    xplordat.com/2018/12/14/want-to-cluster-text-try-c...
    https://www.analyticsvidhya.com/blog/2018/11/tutor...
    https://habr.com/post/346206/
    https://nlpub.ru/
    Ответ написан
    Комментировать
  • Легаси-монстр. Как побеждаете?

    @RidgeA
    Немного банальностей:
    1. Бизнес не даст ресурсов на переписывание проекта с 0: время и большие риски
    2. Бизнесу как правило все-равно какое говно там крутится, лишь бы деньги приносило.
    3. Если более-менее адекватное руководство - нужно донести идею постепенного рефакторинга кода по мере необходимости в процессе фикса багов и разработки новых фич и тем самым аргументировать что на разработку новых фич/фикс багов нужно больше времени.

    Как я бы делал:
    1. Тесты на существующие функции (если возможно, видел методы в контроллерах с мешаниной вызовов методов моделей, созданием DTO и сохранением их через репозиторий, прямых http-запросов и запросов в бд на 1000+ строк, покрыть такое тестами - невозможно)
    2. Составить план рефакторинга, где отметить что и где надо сделать, коротко, в основном для команды разработчиков.
    3. Постепенно рефакторить старый код по мере взаимодействия с ним.
    4. Новый код - писать сразу правильно, для взаимодействия со старым кодом где нет возможности/времени его переделать - делать какие-то адаптеры, что бы не распространять токсичный код.
    5. Как оперативная мера защиты от SQL иньекций можно поставить что-то вроде этого https://github.com/nbs-system/naxsi
    6. Мониторинг кода, который не используется - pinba.org , по мере обнаружения такого кода - удалять безвозвратно (в крайнем случае есть VCS, я надеюсь). Начать с более высокоуровнего кода - контроллеры, напримерю. Плюс IDE в этом могут помочь и grep.
    7. Как вариант - новые фичи можно пилить в отдельном проекте (v2), крутить оба и постепенно переходить на новый, со временем старый (v1) выкинуть (и начать делать новый - v3 :-) )
    Ответ написан
    3 комментария
  • В чем моя ошибка в изучении ЯП?

    ApeCoder
    @ApeCoder
    Поставьте себе небольшую практическую задачу из той области, которая вас интересует: сделать сайт любимой группы или персональную т страничку, приложение на Apache Cordova. А потом учите по мере надобности учите технологии. Интереса больше если есть задача.
    Ответ написан
    Комментировать
  • Как передать io.to('...') как параметр функции?

    @JorJeG
    Здесь у тебя теряется this, как в этом примере
    var name = 'window';
    var obj = {
      name: 'obj',
      show: function() {
        console.log(this.name)
      }
    };
    
    var func = obj.show;
    func();  // Твой случай
    
    obj.show();
    Ответ написан
    2 комментария