• Кнут - "Искусство программирования", как осилить?

    Deerenaros
    @Deerenaros
    Программист, математик, задрот и даже чуть инженер
    Да как же это смешно... Звучит примерно так: имеется интерес освоить хирургию, да только я туп на анатомию и биологию, да и руки кривые, ещё и дрожат. Если не в ладах с математикой, то Кнут не поможет. И вообще, веб-программирование так же относиться к математике, как балет к кулинарии. Сидите смирно и не парьтесь на этот счёт, вероятность того, что Кнут вам чем-то поможет в работе исчезающе мала, тогда как навредить он может на раз-два: можно запросто поймать себя на создании велосипедов.

    Впрочем, варианты есть. Первое, что надо осознать - это дискретная математика. Начинается с арифметики, но вполне можно освоить её параллельно. Тут подойдёт что угодно, хоть учебник за первый-второй курс почти любой технической специальности. Алсо, у самого Кнута есть КонКретная математика. Вполне себе годная писанина, правда для того чтобы проще читалось таки надо иметь хотя бы базовые понятия из дискретной математики: поля с кольцами, да пару свойств. Глубоко копать не стоит. И если что, я предупреждал.

    Впрочем, вместо кнута рекомендую Кормена. Очень даже вещь в себе: её читают как на первом курсе, так и диссертации по ней пишут. И читается проще, и зубодробительной математики в ней нет.
    Ответ написан
    9 комментариев
  • Сколько бpyтфopcить такой пароль?

    @DaNHell
    Change the world
    Да замечательная штука как плановая смена паролей взята не из воздуха, и не по чей то хотелки.
    Рассчитывается из параметров: алгоритм хеширования, минимальные требования к паролю и ~кол-во юзеров.
    В булке например md5(md5($salt).md5($pass)) скорость брута через cuda среднего класса - 152.0 MH/s (150 миллиона хешей в секунду)!
    Ну это конечно прогресс, 21 век.

    Довольно старая таблица, но все-же
    8tvdxh2.png

    Но это мы говорим про полный перебор.
    Но атаки по маске/правилам/словарям/гибридные и конечно же по радужным таблицам делают свое дело на ура.
    Грубо говоря имея дамп 100к юзеров login : (md5), в течении 3-5 минут получаем результат в более чем 50% подобранных паролей.

    Да и также стоит отметить что увеличивать длину пароля конечно же стоит, увеличив на 2 символа (с 10 до 12) грубо говоря усложняем задачу подбора в 300-500 раз.
    НО: Учитывая что это не просто добавление хоть еще 6-8 букв (словосочетаний) словарных/алфавитных.
    Т.е. ItsGoodPassword даже увеличив до ItsReallyVeryGoodPassword пароль, противостоять сможет всего пару секунд гибридной атаке.

    На 2008 год брут через GPU (UPPER CASE + lower case + digs + symbols)
    • all 6 character password MD5s 3 seconds
    • all 7 character password MD5s 4 minutes
    • all 8 character password MD5s 4 hours
    • all 9 character password MD5s 10 days
    • all 10 character password MD5s ~625 days
    • all 11 character password MD5s fuggedaboudit

    Но на получение 12 символьного пароля ушло далеко не несколько лет, а всего 75 дней.

    P.S. От себя добавлю отличный совет: Если есть возможность - используйте нетрадиционные раскладки языка, спец. символы (которые не так уж и сложно прописывать - FAQ По винде поможет).
    Ну а если еще и закреплять это все стойкостью пароля.. То вы в защите от криптографических атак... но далеко не в абсолютной безопасности...
    Ответ написан
    1 комментарий
  • Договор о непереманивании: можно ли обойти?

    xez
    @xez
    TL Junior Roo
    Я был сам в такой ситуации с двумя российским конторами - ничего не получилось.
    Как то тоже наблюдал случай: сотрудник компании А уже договорился в компании Б о трудоустройстве, написал заявление на увольнение, но неожиданно компании А стало известно об этой ситуации. Был большой скандал, компания А потребовала компенсацию.
    В итоге сотрудник уволился из одной конторы, а во вторую его не взяли. Такая история.
    Ответ написан
    Комментировать
  • IOS.Как связать кнопку и ViewController?

    LIAL
    @LIAL
    Сделал вам скриншот - правда сам процесс перетягивания не удалось заскринить - тк кнопки не срабатывают. Но я отрисовал вам синей чертой - что у вас получится
    1. Ткните в xib или сторибоард (что там у вас)
    2. ткните в Asisstan Editor
    3. На кнопке зажмите контрол и кликните мышой не отпуская кнопку мыши и тяните в окно с кодом (ваш ViewController)
    4. Отпустите в месте где хотите чтобы воткнулся метод
    5. Выелзет окно для создания Outlet'a - убедитесь что в списке стоит Action
    6. Дайте название и нажмите Enter - обработчик нажатия кнопки созадн !

    b55a03a593934cd88ad499fe22c711c7.png
    Ответ написан
    1 комментарий
  • Как удалить параметр из this.$router.query в Nuxt.js?

    Martovitskiy
    @Martovitskiy
    Есть такое решение:
    let newRouteQuery = {};
    Object.keys(this.$route.query).forEach(function(key){
        if (key != 's')
            newRouteQuery[key] = this.$route.query[key];
    });
    Ответ написан
    Комментировать
  • Как делать сложные запросы используя репозитории и объединение разных таблиц?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    решением этой несложной задачки.

    Уважаю такой оптимизм.

    Проблема эта не нова. Называется она object-relational impedance mismatch и очень многие считают её в принципе нерешаемой, сравнивая её с проигранной США войной во Вьетнаме.
    Так что можно надеяться на что угодно, только не на простое решение. Но сначала надо проблему осознать. Что отображение объектов на реляционную базу, которое называется object-relational mapping, сокращённо ORM, никогда не бывает простым.

    Отдельно этой теме добавляет остроты терминология. Спроси 10 разных разработчиков что они имеют в виду под репозиторием и под маппингом, и получишь 20 разных мнений. Так что использовать красивые слова следует с очень большой осторожностью.

    К примеру, "нерешаемость" проблемы с impedance mismatch относится к попыткам сделать универсальный ORM, который на вход получает имя любого класса, а на выходе коллекцию объектов. Про такой вариант можно действительно забыть (привет, элоквент-элоквент - и в продакшен!). Но вот полуавтоматическое решение вполне можно накостылить. Главное всегда помнить о проблеме, и как только автоматический маппинг перестаёт работать - тут же от него оказываться в пользу ручного колупания с запросами. Главное этого не бояться и не загонять себя в клетку словами "репозиторий", "один объект-одна таблица" и пр. У тебя есть задача - инстанцировать объект или коллекци объектов из БД. Окей, ты пишешь методы, которые это делают оптимальным способом, не важно - одна там таблица используется, 10 или еще плюс 2 кэша и носкл датабаза в придачу.
    Надо тебе сохранить объект или коллекци объектов в БД? Окей, пишешь метод, коорый делает это оптимальным способом. Да, это куча черной работы. Но зато у тебя будет чистая доменная логика (которая вообще никакого отношения к базе данных или "репозиториям" не имеет).

    Отдельно прекламирую Cycle ORM. Сам я ненастоящий сварщик, но взрослые дядьки говорят что она лучше всего подходит для нормально реализованного маппинга объектов на БД. Лучше чем Доктрина или прости-господи Элоквент. С нетерпением жду доклада автора на ПХПРаша.
    Ответ написан
    1 комментарий
  • Как делать сложные запросы используя репозитории и объединение разных таблиц?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    Совет в лоб. Следуя ООП вы описываете объекты системы объектами из внешнего мира. И все у вас шикарно пока вы не начинаете нормализовывать схему БД. Видимо вас это беспокоит?

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

    Есть бизнес модели, например Группа и Пользователь
    Кроме очевидных 2 таблиц добавляется 3 ПользовательВГруппе
    Вам очевидно нужно только 2 репозитория, 3 репозиторий будет лишним и внесет только путаницу
    Ответ написан
    4 комментария
  • Дает ли строгая типизация в PHP 7 прирост производительности?

    Начал писать ответ комментарий https://toster.ru/answer?answer_id=937197, но ответ получился большим и поэтому решил поместить его отдельно.

    DevMan , я попробую уточнить ваше утверждение, что немного снижает.
    На самом деле, при использовании скалярных тайпхинтов снижается производительность вызова функций, поскольку возникает некий дополнительный оверхед на валидацию аргументов и приведение значений к нужным типам (если не используется strict_types). Но! Так как внутри функции значения аргументов уже приведены к нужным типам, то при использовании аргументов не происходит неявного приведения типа.
    Поясню на синтетическом примере:
    function foo($x) {
        $result = 0;
        for ($i = 0; $i < 100; $i++) {
            $result += $i + $x;
        }
        return $result;
    }


    Если вызвать эту функцию так: "foo('123')", то в таком случае внутри цикла аргумент будет неявно приводится к целому числу 100 раз. Если вызвать функцию так: "foo(123)", то в таком случае аргумент не будет внутри цикла приводится к целому числу. Очевидно, что второй вариант более производительный:
    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.860s
    user    0m0.855s
    sys     0m0.005s

    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.508s
    user    0m0.500s
    sys     0m0.008s


    В то же самое время, если добавить к аргументу скалярный тайпхинт, то тогда значение аргумента один раз будет приведено к тайпхинту и внутри функции уйдёт весь оверхед связанный с неявным приведением типа:
    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.502s
    user    0m0.498s
    sys     0m0.003s

    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.504s
    user    0m0.495s
    sys     0m0.008s


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

    Зато использование строгой типизации не даст запустить функцию в неконтроллируемом состоянии: когда функция ожидает на вход целое число, а по какой-то причине подсунули массив:
    $var = $_GET['foo'];
    bar($var);
    , для get-параметра foo=123 вызов будет корректным, а для foo[]=123 вызов функции приведёт к TypeError; для foo=abc тоже будет TypeError. Разумеется, этот пример сильно надуман и тут нужно использовать "нормальный" валидатор.
    Ответ написан
    1 комментарий
  • Выгрузка товаров с сайта в товары ОК (более 250 товаров), как сделать автоматически?

    @my_market_app_ru
    Некоторое время назад API для автоматической загрузки в ОК добавили. Появились сервисы, как например my-market-app.ru, которые позволяют делать регулярные обновления, конфигурировать шаблоны для описания товаров, дополнительные наценки. Задаешь параметры один раз, дальше всю работу делает робот сервиса.
    Ответ написан
    1 комментарий
  • Чем паттерн Repository отличается от DataMapper?

    trevoga_su
    @trevoga_su
    правильно было бы сформулировать вопрос так - чем ActiveRecord от DM отличается
    DM:
    data-mapper.gif
    AR:
    active-record.gif
    Registry:
    registry.gif
    Ответ написан
    Комментировать
  • Чем паттерн Repository отличается от DataMapper?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Это два абсолютно разных паттерна.

    DataMapper - это то, что традиционно неправильно называют моделью. Тупо мостик между БД и объектом: считать данные из БД и записать в объект, сохранить объект в БД. Фактически CRUD. Способ автоматизировать рутинные операции. Моделью являться не может в силу изначальной ограниченности.
    Другими словами, это универсальный код, подходящий для работы с любыми объектами. Инструмент для работы с БД. Все его методы одинаковы для любых объектов.

    Репозиторий - это то, что на самом деле является моделью - набор методов, реализующих бизнес-логику приложения. Метод в репозитории может включать в себя десяток разных запросов к БД для получения набора данных, необходимого в приложении, плюс их обработку.
    В отличие от DM, репозиторий содержит также уникальные методы, которые отражают конкртеные нужды конкретного модуля приложения.
    Ответ написан
    1 комментарий
  • Как отфильтровать данные по промежуточной таблице-связке (hasMany/hasOne с via/viaTable) в модели Yii2?

    @davidnum95
    return $this->hasMany(ПОСТАВЩИКИ::className(), ['ПОСТАВЩИК_ID' => 'ПРОДАЖИ_ID_ПОСТАВЩИКА'])
             ->viaTable(
                  'ПРОДАЖИ', 
                  ['ПРОДАЖИ_ID_ПОКУПАТЕЛЯ' => 'ПОКУПАТЕЛЬ_ID'], 
                  function ($query) {
                        $query->andWhere(['СТАТУС_ПРОДАЖИ' => 'АКТИВНА']);
                  });
    Ответ написан
    Комментировать
  • Как вызвать Log ошибок в Yii2 Swiftmailer?

    @matperez
    Судя по этому коммиту https://github.com/yiisoft/yii2-swiftmailer/commit... логируется все в общий лог.

    + * In order to catch logs written by this class, you need to setup a log route for 'yii\swiftmailer\Logger::add' category.
     + * For example:
     + *
     + * ~~~
     + * 'log' => [
     + *     'targets' => [
     + *         [
     + *             'class' => 'yii\log\FileTarget',
     + *             'categories' => ['yii\swiftmailer\Logger::add'],
     + *         ],
     + *     ],
     + * ],
    Ответ написан
    Комментировать
  • Почему говорят что jquery не нужен?

    ThunderCat
    @ThunderCat Куратор тега JavaScript
    {PHP, MySql, HTML, JS, CSS} developer
    Скрипач не нужен, родной (с)
    Аргументы против jq:
    - современные браузеры достаточно хорошо поддерживают единый синтаксис современного екмаскрипт(native js)(на самом деле нет).
    - сторонняя библиотека, работает медленнее чем натив и в основном состоит из с-сахара (тоже не совсем правда)
    - тащить еще один ресурс весом от 64 кб до 200 кб, еще и со сторонних ресурсов замедляет загрузку( правда, но бред)
    Аргументы за:
    - Современные браузеры как и всегда один другого "ровнее", всегда есть косяки и "нюансы", на которые еще и попадаешь обычно в самый неподходящий момент, в жк обычно все работает одинаково везде, ну или лучше чем в нативе.
    - В жк реализована куча плюшек в 1 функцию которые в нативе занимают "многабукав", не каждый начинающий напишет их правильно, да и профи не все напишут оптимально, уверен что в большинстве случаев написанный нативом функционал будет хуже аналога из жк.
    - размер мин пакета жк 64 кб, и все они лежат на быстрых цдн серверах. Думаю это последнее что может повлиять на скорость загрузки страницы.
    - есть ОГРОМНОЕ количество скриптов написанных с учетом жк, не использовать их глупо, писать свой велосипед - вообще только в целях обучения(не берем крайние случаи когда плагин писал упоротый пингвин).
    - Синтаксис и краткость записи - вообще вне конкуренции.
    - Старые браузеры никто не отменял, часто заказчик требует чтобы работало в ие8, натив не канает или доставляет море анального удовольствия.
    Вывод: Если ты крут в жс, еще и работаешь в ангуларе/ещечетамдляфронта и тебе нужно сделать 2 действия в очень современных браузерах - jquery не нужен, и ты это сам знаешь. Если слова ангулар, вуе и проч для тебя не больше чем шум листвы за окном, а навесить плагинов и эффектов нужно - jquery наше все.

    UPD: для всех кто там отписался а ля "в связи (...), исчезновением проблемы совместимости со старыми IE (что и было основным назначением jQuery)." - свежачок
    Ответ написан
    4 комментария
  • Как внедрять vue в проект на Yii2?

    copist
    @copist
    Empower people to give
    Ты сборку на базе webpack используешь?

    В Yii2 надо будет сделать два layout: один для обычных страниц (view/layouts/main.php), второй для страниц с Vue (view/layouts/vue.php)

    Для режима dev в файле view/layouts/vue.php нужно подключать JS скрипты, которые генерит npm start. Для этого открой исходный код страницы, которую раздаёт webpack и скопируй оттуда все подключенные <script>. Либо вручную, либо парсер напиши. Вроде бы у этих скриптов статичные имена, поэтому тут проще. Можно один раз скопировать и забыть.

    Для режима prod нужно в лэйауте view/layouts/vue.php подключать финальные сжатые JS скрипты, которые генерит npm run build - тут сложность в том, что эти скрипты с уникальными именами всегда.

    Попробую сделать пример на github
    Ответ написан
    5 комментариев
  • Есть авторитетный сайт с ответами?

    @ipokos
    Которые задаются 1000 раз

    toster.ru
    Ответ написан
    Комментировать
  • Как получить все даты с 01-01-2014 по сегодня с помощью простого mysql-запроса без хранимы процедур?

    Melkij
    @Melkij
    PostgreSQL DBA
    Нельзя.
    Mysql не умеет никакого подобия generate_series. И даже хранимка может лишь вывести список дат. Приджойнить этот список к чему-нибудь другому нельзя.

    К слову, order by 1 - deprecated. "Use of column positions is deprecated because the syntax has been removed from the SQL standard."
    Ответ написан
    Комментировать
  • Yii2 фильтры для товаров?

    webinar
    @webinar Куратор тега Yii
    Учим yii: https://youtu.be/-WRMlGHLgRg
    Можно юзать GridView|ListView, можно написать свой виджет, можно просто html во view файле. Ваш вопрос видимо из разряда "как сверстать", а это вопрос ни как не относящийся к yii.
    Ответ написан
  • Как работать с 2 базами?

    @Kozlovdaniil
    Php/Python developer
    Проще всего написать rest-api, и при любом изменении на одном сайте дёргать api на втором. Да и для получения статистики продаж это самый разумный вариант.
    Средствами yii это легко реализуется.
    Ответ написан
    6 комментариев
  • Функцию, похожую на хэш, с коротким непоследовательным дайджестом и без коллизий?

    @MikeMirzayanov
    Можно так. Работает для всех m от 1 до MOD-1. Если не хватает, то можно либо увеличить константы (тогда может вырасти длина), либо чуток адаптировать алгоритм. Я подогнал, чтобы было как в примере 6 знаков в коде. На самом деле можно все делать в 64-битных переменных, просто так на Java удобнее.

        private static final BigInteger MULTIPLIER = BigInteger.valueOf(13L);
        private static final BigInteger MOD = BigInteger.valueOf(99990001L);
        private static final BigInteger ADDEND = BigInteger.valueOf(699930007L);
    
        public static String encode(long m) {
            if (m <= 0 || m >= MOD.longValue()) {
                throw new IllegalArgumentException("Argument is out of range.");
            }
            return BigInteger.valueOf(m).modInverse(MOD).multiply(MULTIPLIER)
                    .add(ADDEND).toString(36).toUpperCase();
        }
    
        public static long decode(String encoded) {
            return new BigInteger(encoded.toLowerCase(), 36).subtract(ADDEND).divide(MULTIPLIER)
                    .modInverse(MOD).longValue();
        }
    


    Вот примеры того, что получается (для разных m):

    1 BKPXGK
    2 MBOAIK
    3 PWNQV8
    4 RP5H1K
    5 SRUICK
    10000 X2JV9T
    10001 PWMTFN
    10002 U025II
    10003 TRK6AU
    10004 JRJEMK
    10005 UARMRU
    10006 S2NCNJ
    10007 R1E1UK
    10008 HRCMBX
    10009 WU4GN7
    99989996 FVI2O7
    99989997 GY73Z7
    99989998 IQOU5J
    99989999 MBOAI7
    99990000 X2MNK7
    
    Ответ написан
    Комментировать