• Как перенести VDS сервер Ubuntu на другой хостинг?

    Sanes
    @Sanes
    Устанавливать по новой все библиотеки/настраивать все конфиги не вариант

    Чтобы следующий раз не страдать. Настройте ещё раз, но теперь с помощью Ansible.
    Ответ написан
    Комментировать
  • Перестал открываться сайт, как вернуть его в исходное состояние?

    SilenceOfWinter
    @SilenceOfWinter
    та еще зажигалка...
    вам сюда https://freelance.habr.com
    Ответ написан
    Комментировать
  • Обьясните правда ли эти 2 процессоры очень разные по мощности?

    xez
    @xez
    TL Junior Roo
    Процессор - слишком сложная штука для того чтобы делать вывод о его производительности только по количеству ядер и его частоте.
    До пентиума 4, включительно, все было довольно просто: чем больше мегагерц (а потом гигагерц) - тем процессор быстрее. С тех пор прошло уже 20 лет, кстати.
    У Pentium 4EE частота была уже 3.8Ghz и стало как-то понятно, что дальнейшее ее повышение не дает такого сильного прироста к производительности, как и раньше, да и "стоит" значительно дороже. Поэтому производители начали наращивать количество ядер, увеличивать объем кеш-памяти, и, самое главное, улучшать микроархитектуру (микроархитектуру, вобщем-то, они и так всегда улучшали).

    Вот скриншот из AIDA64:
    61c039d0a31d3774198992.png

    Можно заметить, что частоты у процессоров не слишком то коррелируют с их производительностью.

    Поэтому и существуют многочисленные тесты и бенчмарки, по которым можно понять реальную производительность конкретного процессора в конкретной задаче.
    И да, видимо, i5-2500K быстрее чем Athlon II X4 650
    Ответ написан
    Комментировать
  • Какой стек выбрать для бэкэнда?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Началось в колхозе утро.
    Очередной юный мечтатель ковыряет в носу и рассуждает, из чего бы сделать лопату, которой грести денежки.
    При том что из активов у него только то, что из носа и наковырял.

    Нагрузок у него нет, веб-проекта, в котором будет функционал по типу как в Reddit - нет, пользователей нет, рассылок нет, нагрузки даже в 10 пользователей в сутки нет. Как и объяснения, почему пользователи вдруг повалят именно на этот проект.
    Но зато мы уже стррррашно озабочены проблемами с производительностью.
    Поэтому мы убьём в 10 раз больше времени, поднимая на каком-нибудь экзотическом языке прототип, чтобы убедиться что этот проект таки никому не нужен.
    Ответ написан
    4 комментария
  • Как передать на бекенд требования к API?

    @Vitsliputsli
    Многие фронтендеры относятся к беку, как к некой обертке для работы с базой данной. Когда такие становится лидом команды и начинают диктовать свои требования беку, начинается ад, проект даже с простым беком превращается в нечто монструозное, разваливающиеся на ходу. Но, так как снаружи бек не виден, руководство считает, что дело в отдельных тупых бек-разработчиках, которые артачатся, не хотят работать и увольняются.
    Судя по вашим фразам, вы скорее всего один из них. Так как уверены, что приложение - это то, что на фронте, что api - это хрень, которая завязана на отображении информации на фронте, что разработчики бека не нужны при разработке архитектуры и вообще пофиг, что они там делают, главное чтобы давали то, что хочет фронт.
    Но, раз вопрос задан, значит сомнения вас посещают. Поэтому: приложение это не только фронт, а зачастую фронт это не самая сложная его часть. Бек - это не обертка над базой данных, и если вы поменяете значение в базе, это не значит, что к примеру, в потоковом вещании сменится кодек (вот, кому-то может и смешно, а мне в такой ситуации ни фига не было весело). С помощью API получают данные, поэтому не важно, что там у вас напроектировали дизайнеры, или как эти данные выводит фронт, API должен быть универсальным и не зависить от того как вы отображаете данные, поэтому, к примеру, бек может вам дать для получения данных несколько универсальных запросов, а не один специальный. В общем, все гораздо сложнее, и ваш вопрос как состыковать фронт и бек перерастает в вопрос как формировать архитектуру проекта, и как управлять командой.
    Ответ написан
    17 комментариев
  • Как обработать большой объем данных?

    Zoominger
    @Zoominger
    System Integrator
    А зачем через Яву-то дёргать? Можно непосредственно в самой СУБД запланировать. Пример для MS SQL, чтобы было понятно: https://www.osp.ru/winitpro/2017/01/13051261
    Ответ написан
    1 комментарий
  • Как понять что сайт не упадет и не будет виснуть при определенном трафике?

    Adamos
    @Adamos
    Свернуть отзывчивость сайта в трубочку можно буквально ОДНИМ кривым запросом к базе практически на ЛЮБОМ стеке технологий и на ЛЮБОМ оборудовании.
    Так что теоретические изыскания - пальцем в небо. Только практика.
    Ответ написан
    Комментировать
  • Возможно ли стать middle/senior без работы?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Так же, как стать чемпионом бокса, ни разу не выйдя на ринг.
    Ответ написан
    Комментировать
  • Asyncio очень медленно работает во Flask?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Асинхронное программирование
    Седой и строгий
    Flask разрабатывался синхронным и однопоточным. Любые попытки использования конкурентного выполнения в лучшем случае не дадут хороших результатов, а в худшем приведут к непредсказуемым и труднодиагностируемым ошибкам.
    Ответ написан
    Комментировать
  • Как правильно декодировать JSON в UnmarshalJSON?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Есть не очень красивый вариант, но если нужно быстро решить задачу - можно использовать.
    Если у вас нагрузка небольшая - можно его использовать на постоянной основе.
    Если же нагрузка огромная - тогда надо иначе делать.
    Только везде, где символ `_` надо сделать обработку ошибок.
    package main
    
    import (
        "encoding/json"
        "fmt"
        "log"
    )
    
    type TemplateCategory struct {
        ID   int    `json:"id"`
        Name string `json:"name"`
    }
    
    type Template struct {
        Name         string            `json:"name"`
        CategoryInfo *TemplateCategory `json:"category_info"`
    }
    
    func (t *Template) UnmarshalJSON(b []byte) error {
        var result map[string]interface{}
        if err := json.Unmarshal(b, &result); err != nil {
            return err
        }
    
        if t == nil {
            t = &Template{}
        }
        t.Name, _ = result[`name`].(string)
    
        categoryInfo, isMap := result[`category_info`].(map[string]interface{})
        if isMap {
            t.CategoryInfo = &TemplateCategory{}
            t.CategoryInfo.ID, _ = categoryInfo[`id`].(int)
            t.CategoryInfo.Name, _ = categoryInfo[`name`].(string)
        }
    
        return nil
    }
    
    func main() {
        json1 := []byte(`{
            "name": "Мой шаблон",
            "category_info": {
                "id": 109,
                "name": "Тест"
            }
        }`)
    
        json2 := []byte(`{
            "name": "Мой шаблон",
            "category_info": []
        }`)
    
        var data1 Template
        err := json.Unmarshal(json1, &data1)
        if err != nil {
            log.Fatalf(`json1: %s`, err)
        }
    
        var data2 Template
        err = json.Unmarshal(json2, &data2)
        if err != nil {
            log.Fatalf(`json2: %s`, err)
        }
    
        fmt.Printf("data1: %+v\n", data1)
        fmt.Printf("data1.CategoryInfo: %+v\n\n", data1.CategoryInfo)
    
        fmt.Printf("\n\ndata2: %+v\n", data2)
        fmt.Printf("data2.CategoryInfo: %+v\n\n", data2.CategoryInfo)
    }

    Вывод:
    data1: {Name:Мой шаблон CategoryInfo:0xc00000c0c0}
    data1.CategoryInfo: &{ID:0 Name:Тест}

    data2: {Name:Мой шаблон CategoryInfo:}
    data2.CategoryInfo:
    Ответ написан
    7 комментариев
  • Попинайте. Работодатель сказал, что у меня код PHP устаревший. В чем именно проблемы?

    php666
    @php666
    PHP-макака
    die ( mysql_error () );
    последние 10 лет программил
    на зоне программил с отсутствием интернета?

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

    Правда, ищи другую работу. Тебя просто порвут по скилам молодые мальчики.
    Ответ написан
    Комментировать
  • Будет ли чист с юридической точки зрения сайт, позволяющий загружать "пиратские" материалы, но дающий скачивать только список загруженного?

    Adamos
    @Adamos
    Местные мудрецы предпочитают ходить вокруг да около.
    Ну, а я для разнообразия отвечу прямо.
    Закон позволяет либо запрещает - не сайт и прочие технические решения, а деятельность.
    Если вы с помощью этого сайта раздаете контрафактный контент - суду совершенно безразлично, как у вас скачут байтики. Есть факт деятельности, преследуемой по закону? Виновен, если не докажешь, что ты к этой деятельности не имеешь отношения.
    "Это же не я, это просто такой сайт" - для суда не оправдание.
    Ответ написан
    6 комментариев
  • Как правильно использовать интерцепторы в axios?

    owl1n
    @owl1n
    fullstack developer
    Покажу немного практик, как интерцепторы упрощают жизнь мне, да и многим, в целом.
    Здесь и далее покажу именно использование интерцепторов при работе с авторизацией по JWT (токены).

    1) Подстановка хедера авторизации

    const createSetAuthInterceptor = options => config => {
      if (options.access) {
        config.headers.Authorization = options.access;
      } else {
        delete config.headers.Authorization;
      }
      return config;
    };
    
    const setAuthCb = createSetAuthInterceptor(store.state.auth);
    axios.interceptors.request.use(setAuthCb);


    Здесь мы проверям наличие доступа из стора, а точнее, наличие токена. Далее, подставляем, либо удаляем заголовок.

    2) Следующая практика, это обновление токена (то, о чем вы спросили в комментарии, при окончании сессии и т.д.)

    let refreshTokenPromise;
    
    const createUpdateAuthInterceptor = (store, http) => async error => {
      const message = get(error, 'response.data.message');
      if (!['Token expired', 'Invalid token'].includes(message)) {
        return Promise.reject(error);
      }
    
      if (!refreshTokenPromise) {
        refreshTokenPromise = store.dispatch('refreshToken');
      }
    
      await refreshTokenPromise;
      refreshTokenPromise = null;
    
      return http(error.config);
    };
    
    const updateAuthCb = createUpdateAuthInterceptor(store, axios);
    axios.interceptors.response.use(null, updateAuthCb);


    Здесь мы можем видеть, что при каждом ответе проверяем наличие ошибок и если ошибка соответствует ошибке с токеном, то отправляем обновлять токен и далее снова отправляем тот же самый запрос, который к нам вернулся с ошибкой. Тут грамотно будет проверять не само сообщение об ошибке, а код ответа (401 и т.д.), но тут используется такое решение уже из за специфики бэка.

    В этом же решение, вместо обновления токена, можно отправлять юзера авторизовываться самому, на страницу авторизации. Для этого, конечно же, стоит передавать не экземпляр store, а экземляр роутера, чтобы редиректить юзера. Надеюсь, помог и хоть как то наглядно показал способы применения :)
    Ответ написан
    1 комментарий
  • Разработчик недисциплинированно трекает время. Что делать?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    А зачем вообще трекать время? Уложился в дедлайн - молодец. Не уложился - разбор полётов. Хронически не укладывается - понижение грейда или увольнение.
    Ответ написан
    21 комментарий
  • Как работать с JSON-RPC 2.0?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    $apiUrl = "https://api.shiptor.ru/public/v1";
    $apiKey = "YOUR_KEY";
    $client = new \JsonRPC\Client($apiUrl);
    
    // Set headers
    $client->getHttpClient()->withBeforeRequestCallback(function(HttpClient $client, $payload) {
        $client->withHeaders([
            "Content-Type: application/json",
            "x-authorization-token: {$apiKey}"
        ]);
    });
    
    // Fetch something
    $method = "calculateShipping";
    $params = ['paramName'=>"paramValue"];
    $result = $client->execute($method, $params);
    Ответ написан
    2 комментария
  • Java на уровне железа, отличия от C++?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Авторы надеялись, что к железу можно будет обращаться с помощью абстракций - производитель железа у себя реализует java-машину, а уж сверху нее можно запускать прикладной код.

    Вы забываете о большом пласте истории техники, который был сильно до этого - 8 битные домашние ЭВМ (десятки их) и язык Бейсик.

    Так вот, ЭВМ того времени были катастрофически разными - разные носители (кассеты, дискеты, картриджи), разная аппаратура (засунуть еще один центральный процессор в дисковод? да нивапрос! разная скорость для PAL и NTSC версий - легко!). Но вот бейсик был везде и позволял, с некоторыми переделками, таскать программы с машины на машину.

    Таким образом, авторы находились в этом историческом контексте (у них все детство прошло в обнимку с каким-нибудь VIC-20). Тут уже становится логичным желание сотворить то же самое, только круче - берем современный язык, стандартизируем синтаксис - и делаем аналогично - производитель железа предоставляет нам Java-машину с нужным уровнем абстракции - и все программы бегают с архитектуры на архитектуру без переделок.

    Отчасти, это сработало на старых мобилках, в эпоху j2me - это как раз Java, засунутая в телефон - игры, браузеры, карты (были даже ЯндексКарты), читалки, чатилки - куча всего.

    Еще один виток эволюции, которые вы, видимо, не застали - (чорд, я - стар, я очень стар) - попытки сотворить интерактивные веб страницы.
    "У нас же есть всюду переносимая Java - давайте влупим ее поддержку в браузер в виде апплетов - небольших приложений". Тут резко активировались вирусописатели и прочий сброд - благодаря развесистой и дырявой архитектуре, апплеты могли творить всякую дичь.

    Сейчас апплет на java можно встретить во всяком старом железе, на нем там сделано GUI для удаленного администрирования серверов, коммутаторов и СХД. Вы браузером заходите на железку, и тут на вас вываливается ворох предупреждений о том, что сейчас будет запущено какое-то ужасное дырявое ПО, держите штаны, а то слетят. Уверены? Точно уверены? А с этим согласны? А так?

    А уже потом начали активно применять JavaScript, главным образом, изобретя Ajax - продолжая люто натягивать сову (систему для создания электронных библиотек для ученых/HTML) на глобус (задачу создания интерактивного гуя с красивой версткой).

    И это вы еще бэк на Perle не рефакторили
    Ответ написан
    2 комментария
  • Как кешировать изображения в imgproxy?

    Кеша нет. Кеширование решается любым кеширующим прокси или CDN.
    It may be great to have built-in HTTP caching of some kind, but it is way better to use a Content-Delivery Network or a caching proxy server for this, as you will have to do this sooner or later in the production environment.
    Ответ написан
    2 комментария
  • Слетела windows из за линукса, что делать?

    Zoominger
    @Zoominger Куратор тега Windows
    System Integrator
    Восстановить загрузчик Windows (инструкций полно) и больше не играть в хакера.
    Ответ написан
    3 комментария
  • Почему не удается авторизоваться spring rest jwt?

    @dreven Автор вопроса
    Решил проблему, оказывается когда я в UserDetailsServiceпередавал объект в методе loadUserByUsername, который был создан на основе UserDetails, забыл в геттерах username и password вернуть объекты, и не надо отправлять хешированный пароль. Все работает.
    Метод:
    @Override
        @Transactional
        public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    
            User user = userRepository.findByUserName(userName)
                    .orElseThrow(() ->
                            new UsernameNotFoundException("User not found with username: " + userName)
                    );
           UserPrincipal userPrincipal = UserPrincipal.create(user);
           logger.info("user with name: {} succesfully loaded", userPrincipal.getUsername());
           return userPrincipal;
        }


    Объект:
    @Data
    @Builder(toBuilder = true)
    @NoArgsConstructor
    public class UserPrincipal implements UserDetails {
    
        static Logger logger = LoggerFactory.getLogger(UserPrincipal.class);
    
        private Long id;
    
        private String name;
    
        private String username;
    
        private String lastname;
    
        private String middlename;
    
        private String password;
    
        private Collection<? extends GrantedAuthority> authorities;
    
        public UserPrincipal(Long id, String username, String name, String password, String lastname, String middlename, Collection<? extends GrantedAuthority> authorities) {
            this.id = id;
            this.name = name;
            this.username = username;
            this.lastname = lastname;
            this.middlename = middlename;
            this.password = password;
            this.authorities = authorities;
    
        }
    
        public static UserPrincipal create(User user) {
            logger.info(user.toString());
            List<GrantedAuthority> authorities = user.getRoles().stream().map(role ->
                    new SimpleGrantedAuthority(role.getRole())
            ).collect(Collectors.toList());
    
            return new UserPrincipal(
                    user.getId(),
                    user.getUserName(),
                    user.getName(),
                    user.getPassword(),
                    user.getLastName(),
                    user.getMiddleName(),
                    authorities
            );
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }
    
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public String getUsername() {
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            UserPrincipal that = (UserPrincipal) o;
            return Objects.equals(id, that.id);
        }
    
        @Override
        public int hashCode() {
    
            return Objects.hash(id);
        }

    @PostMapping("/signin")
        public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
            String username = loginRequest.getUserName();
            String password = loginRequest.getPassword();
            Authentication authentication;
            try {
                authentication = authenticationManager.authenticate(
                        new UsernamePasswordAuthenticationToken(
                                username,
                                password
                        )
                );
            } catch (AuthenticationException e) {
                logger.error("Invalid username/password supplied");
                throw new BadCredentialsException("Invalid username/password supplied");
            }
            SecurityContextHolder.getContext().setAuthentication(authentication);
    
            String jwt = tokenProvider.generateToken(authentication);
            return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    
        }
    Ответ написан
    Комментировать
  • Какую авторизацию сделать на сайте?

    Lebezniy
    @Lebezniy
    Веб разработка
    Можете рассмотреть вариант использования JWT в PHP: Авторизация на сайте с JSON Web Token
    Ответ написан
    4 комментария