• Как повысить уровень программирования?

    tiabc
    @tiabc
    Бизнес-партнер и консультант по технологиям
    Хорошие разработчики постоянно развиваются и никогда не стоят на месте. Любое развитие состоит в делании дел, в решении конкретных задач и в обратной связи, которую ты получаешь от других или в результате рефлексии.

    TL;DR: Читайте книжки, делайте дела, читайте чужой код.

    Что можно начать делать прямо сейчас, чтобы стать программистом лучше?

    1. Изучайте базу. Алгоритмы, сети, криптографию, архитектуру, ос, устройство браузеров, компиляторы и т.д. Изучение подобных вещей дает понимание какие задачи бывают в реальном мире и как "большие дядьки" решают возникающие проблемы. Это кладезь инсайтов.

    2. Устройтесь на фултайм-работу с сильной командой даже если джуниором. Я считаю, что есть только один способ расти как разработчик: работать фултайм над одним бизнес-продуктом. Такой подход учит решать проблемы масштабируемости, думать заранее, работать над процессом, которому вы следуете в разработке, решать задачи, возникающие с длительной эксплуатацией, решать проблемы с удобными окружениями и вообще учиться планировать свою работу в связи с нуждами бизнеса.

    3. Написание кода - не самая большая часть работы сеньор-девелоперов, я бы сказал. Но когда речь заходит о самом коде, нужно понимать что ты пишешь и зачем. Есть классические книжки, которые можно найти, например, в матрице компетентности программиста, есть современные, но полезные типа The Art of Readable Code, которую я очень рекомендую. Нужно читать книжки. На собеседовании я всегда спрашиваю какие книжки читал или читает соискатель и если ответ отрицательный, то это большой минус.

    4. Участвуйте в опенсорс. Там вам всегда приходится сталкиваться с образом мысли самых разных людей и кодом, который они пишут. Это учит вас читать чужой код, находить в нем ошибки и критически и аргументированно к нему относиться, предлагая свои решения. Опенсорс-разработка, так же как и книжки, дает вам тот чужой опыт, который бы вы никогда сами не получили от людей, которые часто умнее или опытнее вас в чем-то. В опенсорсе, кстати, в отличие от бизнесовой разработки, есть шанс в удовольствие писать очень качественный код, в котором в бизнесе далеко не всегда есть необходимость.

    5. Наберитесь терпения. Это не случится за один день. Думайте над именованием, разделяйте обязанности, изучайте алгоритмы и экосистему, оптимизируйте ваше рабочее место, изучайте новые технологии, читайте статьи и в течение ближайших лет регулярных усилий вы обретете новый способ мышления и будете разрабатывать поддерживаемое и надежное ПО. Легкого пути, к сожалению, нет.
    Ответ написан
    2 комментария
  • Где лучше проверять права пользователя - модель/контроллер/%else%?

    tiabc
    @tiabc
    Бизнес-партнер и консультант по технологиям
    С системой прав всегда сложно работать и всегда нужно смотреть на конкретную реализацию и учитывать как она будет изменяться в будущем. В любом случае, я сейчас слегка включен в работу над подобной задачей в нашей компании и попробую дать какой-то полезный ответ.

    В контроллере действительно проверять стоит только простые кейсы и недостаток проверки в контроллере как раз в том, что если, например, реализовали проверку в одном HTTP-контроллере и вдруг появляется CLI-контроллер, то хочется чтобы вызовы доменной логики были одинаковыми с любого места, включая валидацию. Соответственно, попробуем унести проверку доступа в другое место.

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

    Как вы написали, у вас есть некий набор прав и некие действия (модерация, редактирование) с некоторыми параметрами (поля для редактирования), которые можно производить над моделью. Соответственно, сформулируем какое-то решение. Оно может вам совершенно не подойти, это лишь простой вариант пальцем в небо, который иллюстрирует подход. Введем PolicyChecker с методами в духе canCreatePost(user, createPostRequest) bool, где каждый метод соответствует проверке конкретного действия с конкретными параметрами запроса у конкретного пользователя. Этот PolicyChecker все знает про авторизованных пользователей, про роли, группы и что бы то ни было у них есть, а если ему нужны дополнительные зависимости для проверки, они передаются ему в конструкторе или какой там у вас подход к управлению зависимостями.

    Таким образом, в каждом контроллере вы на основе PolicyChecker'а сможете проверить, что данный пользователь авторизован на данное действие. Если появится еще один контроллер, то придется эту проверку писать заново и я считаю, что это правильно, т.е. PolicyChecker'ы могут быть опять же разные для разных контроллеров и правила проверки в них могут отличаться. Либо может быть необходимость вообще выполнить действие над моделью без авторизованного пользователя, как уже писал выше, и тогда никакие права можно и не проверять и просто забыть про PolicyChecker.

    Конкретная реализация опять же зависит от вашего конкретного юз кейса и систему прав нужно хорошенько проектировать в связи с нуждами бизнеса потому что она имеет свойство лавинообразно разрастаться и приводить к сложностям в поддержке кода и вообще уязвимостям.

    Надеюсь, мои рассуждения оказались вам полезны.
    Ответ написан
    2 комментария
  • Что почитать/посмотреть про устройство интернета?

    tiabc
    @tiabc
    Бизнес-партнер и консультант по технологиям
    На самом деле, если хочется быстро и детально разобраться как устроен интернет, при этом не охренев, то есть замечательная книжка под названием "Networks: Top-Down Approach". Там все рассказывается сверху вниз от понятных "обычному человеку" протоколов, которые у нас перед глазами, к более низкоуровневым протоколам, которые нам видно хуже. А если хочется не просто познакомиться, но еще и разобраться, то в книжке есть упражнения. А Таненбаума я бы, на самом деле, брал второй книгой когда уже будет какая-то база и захочется еще больше подробностей.

    https://www.amazon.com/Computer-Networking-Top-Dow...
    Ответ написан
    Комментировать
  • Как вызывать и работать с exe файлом с помощью golang в windows?

    tiabc
    @tiabc
    Бизнес-партнер и консультант по технологиям
    В дополнение к ответу Александра, если требуется не только прочитать какие-то данные из сторонней программы, но еще и что-то ввести в ее стандартный поток ввода (как я понял, основная задача именно в этом), можно поступить так:

    package main
    
    import (
    	"fmt"
    	"log"
    	"os/exec"
    )
    
    func main() {
    	cmd := exec.Command("cmd", "/C", "C:/gopath/src/script/for.exe")
    
    	// Чтобы вводить что-то в стандартный поток ввода другой программы, нужно получить ее pipe.
    	pipe, err := cmd.StdinPipe()
    	if err != nil {
    		log.Fatal(err)
    	}
    	// Куда впоследствии можно что-то писать.
    	pipe.Write([]byte("piggybank"))
    	// После ввода всех данных нужно обязательно его закрыть.
    	pipe.Close()
    
    	// Самый простой способ получить вывод другой программы, использовать:
    	output, err := cmd.Output()
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Print(string(output))
    }
    Ответ написан
    1 комментарий
  • Как в go получить результат sql запроса по частям?

    tiabc
    @tiabc
    Бизнес-партнер и консультант по технологиям
    Позволяет по дефолту, но не по тысяче строк, а в виде курсора, который двигается при каждом вызове rows.Next(), о чем подробнее можно прочитать в документации database/sql:
    https://golang.org/pkg/database/sql/#Rows

    Там же есть пример, который это иллюстрирует:
    rows, err := db.Query("SELECT ...")
    ...
    defer rows.Close()
    for rows.Next() {
        var id int
        var name string
        err = rows.Scan(&id, &name)
        ...
    }
    err = rows.Err() // get any error encountered during iteration
    ...


    Только в Go для конкретных баз данных написаны разные драйверы: https://github.com/golang/go/wiki/SQLDrivers
    И хорошо бы заранее проверить в исходниках, что драйвер, который вы используете, действительно использует курсор внутри, а не считывает, например, сразу все в слайс и выдает элементы из него по одному.
    Ответ написан
    Комментировать