• 10 000 строчек проще рефакторить или переписать?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Обычно код такого качества проще переписать. Есть и дополнительные плюсы:
    - вы в деталях поймёте, как работает проект и что делает;
    - вы, вероятно, найдёте и исправите какие-то баги по дороге.

    Но это индивидуально, вообще. Кому-то проще инкрементально рефакторить, лично мне проще в такой ситуации писать с нуля, ориентируясь на имеющийся код, но критически его оценивая.
    Это и от размеров проекта ещё зависит, от общей его сложности, от нагрузки на разработчиков (можно ли остановить активную разработку на какое-то время). 10k строк, в принципе, не очень большой размер.
    Ответ написан
    Комментировать
  • Как объявлять использовать файлы d.ts в PHPStorm?

    Kozack
    @Kozack
    Thinking about a11y
    как сделать, чтобы PHPStorm подхватывал файлы d.ts на автомате?

    Ваш d.ts файл должен быть подключен в tsconfig.json

    где хранить эти d.ts файлы?

    Где вам удобно

    как сделать, чтобы PHPStorm понимал, из какого файла применять описание типов для текущего файла

    Тут два варианта.
    Ваши типы зарегистрированы глобально. Указывать из какого файла нет нужны.
    Типы не глобальные или есть конфликт имён. Обычный import type { ... } from ...
    Ответ написан
    2 комментария
  • Курс или полный гайдлайн по git?

    Griboks
    @Griboks
    Ответ написан
    Комментировать
  • Как организовать код в интерфейсы golang?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Интерфейс нужно будет указывать как параметр функций, которые будут уметь работать с вашим интрейфейсом.
    Например.
    func Process(device test123.Command) {
        device.Open()
        device.Close()
    }
    
    dev1 := a123.A123struct{параметры...}
    Process(dev1)
    
    dev2 := b123.B123struct{параметры...}
    Process(dev2)
    
    // или с перечислением
    devices := []test123.Command{dev1, dev2}
    for _, device := range devices {
        Process(device)
    }


    Приведу пример более похожий на реальный.
    Допустим нам нужно сделать логгер, который умеет писать в файл (если указан в настройках), а если не указан - тогда в консоль.
    Пример намеренно упрощён, чтобы было проще уловить суть.
    package main
    
    import (
        "fmt"
        "os"
    )
    
    // Logger интерфейс логгера.
    type Logger interface {
        Error(msg string)
    }
    
    // StdoutLogger реализация интерфейса Logger для вывода сообщений в консоль.
    type StdoutLogger struct{}
    
    // NewStdoutLogger конструктор (возвращаем структуру, не интерфейс)
    func NewStdoutLogger() *StdoutLogger {
        return &StdoutLogger{}
    }
    
    // Error добавляет в лог сообщение с уровнем error
    func (l *StdoutLogger) Error(msg string) {
        fmt.Printf("ERROR: %s\n", msg)
    }
    
    // FileLogger реализация интерфейса Logger для вывода сообщений в файл.
    type FileLogger struct {
        FileName string
        Fh       *os.File
    }
    
    // NewFileLogger конструктор.
    func NewFileLogger(fileName string) *FileLogger {
        logger := &FileLogger{
            FileName: fileName,
        }
        fh, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0664)
        if err != nil {
            panic(fmt.Sprintf("FileLogger: can't open log file: %s: %s\n", fileName, err))
        }
        logger.Fh = fh
    
        return logger
    }
    
    // Error добавляет в лог сообщение с уровнем error.
    func (l *FileLogger) Error(msg string) {
        l.Fh.WriteString(fmt.Sprintf("ERROR: %s\n", msg))
    }
    
    // ProcessData какая то функция, которая использует логгер и которую не должна беспокоить реализация логгера.
    // Тут тип параметра должен быть интерфейс.
    func ProcessData(logger Logger) {
        logger.Error("Data process some error happened")
    }
    
    func main() {
        var logger Logger
    
        // если лог файл не указан - используем StdoutLogger, если указан - используем FileLogger
        logFile := os.Getenv("LOG_FILE")
        if logFile != `` {
            logger = NewFileLogger(logFile)
        } else {
            logger = NewStdoutLogger()
        }
    
        ProcessData(logger)
    }

    После запуска go run main.go вы увидите сообщение в консоли:
    ERROR: Data process some error happened
    а если запустите вот так LOG_FILE=test.log go run main.go
    или
    export LOG_FILE=test.log
    go run main.go

    То будет создан файл test.log и туда будет добавлено тоже сообщение, что вы видели в консоли.

    Если понятнее не стало - пишите, будут рад помочь.
    Ответ написан
    2 комментария
  • Как быстро усвоить большой объем информации?

    Zoominger
    @Zoominger Куратор тега IT-образование
    System Integrator
    С теми подробностями, что вы привели, правильный ответ - а чёрт его знает.

    Но в любом случае - не существует никакой волшебной таблетки или методики, которая вас быстро сможет научить чему-то, это миф.

    Единственный совет, который могу дать - не изучать что-то более, чем 3-4 часа, потому что человек утомляется и ничего нового при задрачивании по 8 часов подряд не усвоится.
    Ответ написан
    2 комментария
  • На сколько подходят друг к другу эта плата и планка оперативной памяти?

    Zoominger
    @Zoominger
    System Integrator
    Тайминги - ерунда.
    Ставьте.
    Ответ написан
    Комментировать
  • Работа с goroutines?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Есть несколько вариантов решения задачи
    передавать не указатель, а значение

    package main
    
    import (
      "fmt"
      "time"
    )
    
    var c = make(chan int, 3)
    var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    func main() {
      fmt.Println("Hello, playground")
      go save()
      go read()
      time.Sleep(3 * time.Second)
    }
    
    func save() {
      for _, val := range data {
        c <- val
      }
    }
    
    func read() {
      for {
        val := <-c
        fmt.Println("read:", val)
      }
    }

    скопировать значение и передать указатель на это значение

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    var c = make(chan *int)
    var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    func main() {
    	fmt.Println("Hello, playground")
    	go save()
    	go read()
    	time.Sleep(3 * time.Second)
    }
    
    func save() {
    	for _, val := range data {
    	        v := val
    		c <- &v
    	}
    }
    
    func read() {
    	for {
    		val := <-c
    		fmt.Println("read:", *val)
    	}
    }

    передать правильный указатель, на элемент данных

    package main
    
    import (
    	"fmt"
    	"time"
    
    
    var c = make(chan *int, 5)
    var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    func main() {
    	fmt.Println("Hello, playground")
    	go save()
    	go read()
    	time.Sleep(3 * time.Second)
    }
    
    func save() {
    	for i := range data {
    		c <- &data[i]
    	}
    }
    
    func read() {
    	for {
    		val := <-c
    		fmt.Println("read:", *val)
    	}
    }



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

    Вот пример, который покажет, что адрес всегда один и тот же
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    var c = make(chan *int, 5)
    var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    func main() {
    	fmt.Println("Hello, playground")
    	go save()
    	go read()
    	time.Sleep(3 * time.Second)
    }
    
    func save() {
    	for _, val := range data {
    		c <- &val
    		fmt.Printf("write: %v\n", &val)
    	}
    }
    
    func read() {
    	for {
    		val := <-c
    		fmt.Println("read:", *val)
    	}
    }

    Вывод будет таким (адрес один и тот же)
    Hello, playground
    write: 0xc000094000
    write: 0xc000094000
    write: 0xc000094000
    write: 0xc000094000
    write: 0xc000094000
    write: 0xc000094000
    ...


    А в такой реализации (2й пример)
    func save() {
    	for _, val := range data {
    		v := val
    		c <- &v
    		fmt.Printf("write: %v\n", &v)
    	}
    }

    тут вывод будет таким (каждый раз новый участок памяти)
    Hello, playground
    write: 0xc000094000
    write: 0xc000094010
    write: 0xc000094018
    write: 0xc000094020
    write: 0xc000094028
    write: 0xc000094030

    В третьем варианте тоже будут разные указатели.
    Ответ написан
    5 комментариев
  • Как соединить двойное подчеркивание?

    vmakhnyuk
    @vmakhnyuk
    Frontend developer
    Вам нужен шрифт, который поддерживает лигературы.
    Пример бесплатных шрфитов:
    * https://github.com/tonsky/FiraCode
    * https://www.jetbrains.com/lp/mono/
    Ответ написан
    Комментировать
  • Как соединить двойное подчеркивание?

    delphinpro
    @delphinpro Куратор тега HTML
    frontend developer
    Включите лигатуры в настройках.
    И используйте шрифт с лигатурами.
    Встроенный шрифт Jetbrains Mono или, например, Fira Code.
    Ответ написан
    Комментировать
  • Как написать свою тему для конкретного типа файлов?

    Aetae
    @Aetae
    Тлен
    Settings -> Editor -> File Types -> +
    Ответ написан
    Комментировать
  • Где Pycharm хранит плагины в системе?

    Комментировать
  • Как убрать ошибки в коде?

    @MaLikoV
    Переписать весь код, в вашем коде отсутствует логика.

    Например строка 5, если ответ на вопрос "Ты хочешь записаться на курсы?" == "нет" что должно произойти? Я не понял и питон не понял. Прочтите что на писано и в голове проследуйте за логикой написанного, увидите все ошибки.

    Такое ощущение что вы взяли код и не понимая его меняете.

    Как должно было бы выглядеть
    print("Привет!")
    print("Тебя приветствует IT школа GeekTech!")
    test1 = input("Ты хочешь записаться на курсы?")
    if test1 == "да":
        print("Хорошо")
    elif test1 == "нет":
        print("Гудбай")
    else:
        print('Принимаю только да или нет')
        
    test3 = input("Тебе когда нибудь давали чапалах со скоростью света?")
    if test3 == "нет":
        print('Алакикаджи')
    else:
        print('Как скажешь')
    Ответ написан
    1 комментарий
  • Как укоротить максимальную длину кода на строке?

    delphinpro
    @delphinpro Куратор тега PhpStorm
    frontend developer
    В настройках код-стайла. Общее и отдельно для каждого типа файлов.

    60dee5ed6b5f3309415321.png

    Уже набранный код можно переформатировать

    60dee6351cba3970417027.png
    Ответ написан
    Комментировать
  • Как правильно создать HTML письмо?

    AntonLitvinenko
    @AntonLitvinenko
    HTML coder
    Рекомендую воспользоваться фреймворком MJML, если есть опыт вёрстки, то разобраться с ним пара часов, хорошая документация, есть примеры, онлайн песочница, приложение для компа и возможность запустить под галпом
    Ответ написан
    Комментировать
  • Как разделить окно на два, как в Sublime?

    sslion
    @sslion
    60d71bbbc9ef9660846715.png
    Не за что...
    Ответ написан
    Комментировать
  • Стоит ли начинать карьеру в SEO?

    kab7771s_sinelnikov
    @kab7771s_sinelnikov
    Конечно стоит попробовать, если "душа лежит", хоть сейчас много систем автоматизации (типа Rookee), всё равно каждый сайт необходимо наполнять и продвигать в ТОП, а как это сделать знают не многие. Причём понимание SEO даст возможность узнавать такие сферы как контекстная и таргетированная реклама, ASO (продвижение мобильных приложений), веб-разработка и так далее. А органический поиск никуда не денется покуда есть Интернет.

    imho
    Ответ написан
    Комментировать
  • Возможно ли фрилансить на Си?

    nki
    @nki
    bezkart.ru готовая система лояльности
    Для ответа на ваш вопрос нужно зайти на популярные биржи и поискать заказы на Си. Проанализировать результат.
    Сами справитесь?
    Ответ написан
    Комментировать
  • Является ли счёт на Апворк электронным кошельком?

    Jump
    @Jump
    Системный администратор со стажем.
    Нет, счет на Апворк это просто внутренняя бухгалтерия Апворка, и ничего более. Там записано сколько вам должны.
    Это не ваши деньги.
    Ответ написан
    Комментировать
  • Как заработать программисту на С#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Устроиться работать в компанию, где нужны специалисты с вашими знаниями.

    Искать не на бирже фриланса, а на hh
    Ответ написан
    Комментировать