• Почему некоторые современные CMS не связывают свои таблицы в БД?

    @dinegnet
    Потому что они связывают на прикладном уровне движка.
    Давным давно уже не модно использовать все мыслимые возможности конкретной СУБД.
    Хотя бы по той причине, что сие заставляет слишком уж привязываться к конкретной СУБД.

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

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

    Потому вам и проще. Решать примитивные вопросы всегда проще.
    По сути вы не проблемы конечного заказчика тем самым решаете - а свои.

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

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

    Еще одна причина - полноценная реляционная модель со интересующими вас связями плохо ложится на многие прикладные задачи, решаемые на CMS.
    Бессвязанные таблицы позволяют делать решение гибче, приближая реляционные СУБД к СУБД No-SQL

    Перенос логики из БД в движок позволяет многие задачи решать лучше. Например, такую важную вещь как кэширование. Да и много других.
    Ответ написан
    8 комментариев
  • Кто ни будь видел сайты с примерами рефакторинга?

    @MoonMaster
    Программист и этим все сказано
    Может быть вы имеете в виду вот этот сайт
    Ответ написан
    2 комментария
  • Как отправить значение переключателя на бекенд?

    myspace
    @myspace
    ajax по событию что угодно отправляет, хоть координаты мыши

    $('#checkbox').change(function() {
        if($(this).prop('checked')) {
            $.ajax({
    ///
    ///
                 data: {
                      prop: $(this).data('propertyName')
                  } 
    //
    //
             });
        }
    });
    Ответ написан
    9 комментариев
  • Как в регулярном выражении указать "и буквы и цифры", но не что-то одно?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Например, так:
    [a-z0-9]*(?:[a-z][0-9]|[0-9][a-z])[a-z0-9]*
    Ответ написан
    Комментировать
  • Как работает алгоритм быстрой сортировки?

    zagayevskiy
    @zagayevskiy
    Android developer at Yandex
    Вот вам даже видео https://youtu.be/ywWBy6J5gz8
    А так читайте в интернетах.
    Ответ написан
    Комментировать
  • Как отключить рекламу на Youtube?

    @balamyt92
    ; select * from users; --
    Ставим это

    ПКМ и пункт Параметры
    637cc0d4085e47dbaf108aebee634758.png

    Выбираем нужные фильтры для региона и забываем о рекламе
    02f1b49064b44bdea3a6f0345a1528ff.png
    Ответ написан
    6 комментариев
  • Сколько последних версий браузеров вы поддерживаете?

    gobananas
    @gobananas
    finishhim.ru
    Так вот же https://www.npmjs.com/package/bootstrap-sass
    To match upstream Bootstrap's level of browser compatibility, set Autoprefixer's browsers option to:
    [
      "Android 2.3",
      "Android >= 4",
      "Chrome >= 20",
      "Firefox >= 24",
      "Explorer >= 8",
      "iOS >= 6",
      "Opera >= 12",
      "Safari >= 6"
    ]
    Ответ написан
    Комментировать
  • Какие службы используются и какие задачи выполняются при работе Postfix или Exim?

    @Tabletko
    никого не трогаю, починяю примус
    man postfix, man exim. Так же рекомендую почитать книжку "администрирование Postfix", есть перевод на русский. Там детально описывается какой процесс за что отвечает. Rtfm, в общем)
    Ответ написан
    3 комментария
  • Не студия и не новичок - почему?

    gobananas
    @gobananas
    finishhim.ru
    Потому что в цену студии заложены:
    1) Офис
    2) Налоги
    3) Менеджеры/бухгалтерия/секретарши
    4) Перекуры всех сотрудников из п.3.
    Список при желании можно продолжать долго и бывает что проект за 500 тыс. рублей пилит в студии один программист джун с з/п 20к
    Поэтому заказчик хочет что бы его деньги ПОЛНОСТЬЮ достались непосредственному исполнителю
    Ответ написан
    Комментировать
  • Какое регулярное выражение написать?

    gobananas
    @gobananas
    finishhim.ru
    Если в preg_replace будете вставлять для удаления то как-то так https://www.regex101.com/r/jFfVQq/1 (расширение .zip оставил)
    Ответ написан
    1 комментарий
  • Несколько вопросов о mongodb?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Я работаю с MongoDB уже более 3 лет, поэтому буду рассказывать и давать советы опираясь на личный опыт эксплуатации.

    Получается, что нас всю жизнь учили данные нормализовывать и объясняли, почему это хорошо, а теперь все с точностью наоборот?

    Не совсем. Вас учили работать только с одной разновидностью баз данных - реляционной. Теперь вы увидели, что бывают еще и другие, документ-ориентированные. Разумеется, в каждой разновидности будут свои подходы к хранению и организации данных.
    Это не хорошо и не плохо, это иначе.
    Несомненно, ажиотаж вокруг термина NoSQL существует. И на то есть причины, в основном то, что данных действительно стало больше. Информационная энтропия увеличивается и ее все сложнее укладывать в рамки реляционных баз данных. Здесь можно долго рассуждать, но могу с уверенностью сказать, что сейчас появился спрос на такие хранилища, в которых структуру нужно менять более быстро, чем это могут позволить реляционные базы данных.

    Объясните, пожалуйста, на пальцах, правильно ли я все понимаю?

    По большей части вы правы. Это денормализованные данные, но с определенными моментами. Я покажу вам их на вашем же примере.

    Как в монго при этом обновлять данные, которые хранятся в каждом документе?


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

    Типичная запись в ней выглядит так
    {
        "_id" : ObjectId("5801aa17964c6b2a050041a7"),
        "title" : "New Book",
        "authors" : [ 
            {
                "_id" : ObjectId("5801aa0f964c6b26030041a9"),
                "firstName" : "Phil",
                "lastName" : "Tkachev"
            }
        ]
    }


    И я хочу заменить имя в тех книгах, в которых я - автор, то мой запрос будет выглядеть так:

    db.getCollection('book').update(
     {'authors._id':ObjectId("5801aa0f964c6b26030041a9")}, 
     {$set: {'authors.$.firstName': 'Philipp'}  }, 
     {multi: true } 
    )


    Здесь есть ряд разных сценариев, просто почитайте документацию. В ней все неплохо расписано.

    Приемлемо ли в монго денормализовывать данные, чтобы хранить данные в отдельной коллекции, и обращаться к ним отдельным запросом (ведь джоинов там нет)?


    Есть ряд случаев, когда так и делают. Например есть разного рода ORM, тот же Mongoose, который так и делает.

    И принято ли так работать?


    И да, и нет. Когда вы работаете с такого рода базой данных, вам нужно подходить к организации данных исходя из решаемой проблемы, отталкиваться от проекта будущего приложения или решения задачи.
    Вам просто нужно ответить на вопрос, что дешевле, запросить документ по ключу или обновить запись внутри документов.
    Взять к примеру, ваш сайт, в котором есть новости и их авторы. Новости могут читать миллионы, а значит при обращении к каждой новости нужно будет делать подзапрос на информацию о каждом авторе. Т.е. вместо одного запроса, при просмотре новости, нужно будет делать 2. А если показывать список из 100 новостей? Будете делать 100 вторичных запросов? Нет, это тоже неправильно. Нужно будет получить список новостей, в коде приложения собрать идентификаторы авторов, сделать второй подзапрос, получить информацию об авторах, затем объединить ее с уже полученным списком статей. Это немного усложнит ваше приложение, но тоже позволит сэкономить ресурсы. Если вы встроите авторов внутрь статьи, это позволит вам обойтись одним запросом к базе, хоть на просмотр, хоть на список новостей. С другой стороны вам прийдется подумать об обновлении информации об авторе. Но, т.к. такая информация меняется сравнительно редко, то есть смысл встраивания.

    Что делать, если изменилась структура данных, если структуры то и нет?


    Здесь все просто. Когда вы разрабатываете свое приложение, вы изначально закладываете в него обработку изменений. Например, вы можете добавить поле версии документа, в котором храните номер версии структуры и реагировать на ее изменение в коде. Либо вы можете просто писать приложение таким образом, что оно автоматически будет конвертировать структуру из старой в новую при первом обращении.

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

    Коллекция новостей:

    {
    	_id: 'MongoId',
    	title: '',
    	body: '',
    	author: {
    		_id: 'идентификатор пользователя',
    		name: 'Имя пользователя',
    		subscribers: 'Количество подписчиков'
    	}
    }


    Автор является неполной копией данных о пользователе. Это поможет сэкономить место и позволит избежать ненужных запросов.

    Коллекция пользователей:

    {
    	_id: 'MongoId',
    	name: 'Имя пользователя',
    	email: '',
    	roles: ['user', 'author', 'admin'],
    	subscribers: 'Number'
    }


    Список ролей может опеределять уровень доступных возможностей. Его легко изменить, можно легко найти авторов или админов.

    Коллекция подписок:

    {
    	initiator: {
    		_id: 'идентификатор пользователя, который инициировал подписку',
    		name: 'Имя пользователя'
    	},
    	target: {
    		_id: 'идентификатор автора',
    		name: 'Имя пользователя'
    	},
    	date: 'ISODate',
    	confirmed: 'bool'
    }


    Здесь вы можете подстроить, как список подписок, так и список подписчиков одним запросом.
    Ответ написан
    1 комментарий
  • Препроцессор, какой выбрать?

    Sanes
    @Sanes
    Препроцессор в 2017 году. Какой выбрать?

    Такой же, что в 2016 и в 2015
    Ответ написан
    2 комментария
  • Что почитать об архитектуре CMS?

    dmitriylanets
    @dmitriylanets
    веб-разработчик
    нет правильной архитектуры CMS
    Ответ написан
    Комментировать
  • Как в редакторе Atom оставить только одно окно?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    В настройках отключить пакет welcome
    6973c5f4d8be458ea350f0154ed16915.png
    Ответ написан
    Комментировать
  • Для чего нужен singleton?

    @MarkusD
    все время мелю чепуху :)
    В буквальном смысле синглтон призван упростить владение, инициализацию, контроль времени жизни и доступ к элементам глобального состояния программы. Эта фраза является самой важной. А важнее всего - правильно понять ее.

    Подход многократно обличался антипаттерном за то, что "глобальное состояние программы - это зло", не смотря на то, что глобальное состояние продолжает оставаться в программе даже после удаления всех синглтонов из проекта.
    Я видел проекты с более чем 50 синглтонами и очень тяжелыми проблемами их связи между собой. В синглтоны без разбора и по незнанке вытаскивали буквально все. Это яркий пример антиподхода применения абсолютно любого паттерна.
    Важно понимать что никакой элемент проектирования не является антипаттерном, он приводит к проблемам только при неумелом использовании.

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

    В качестве альтернативы синглтонам пропагандируются два других подхода: Registry / Service locator и Dependency injection.
    К слову, все альтернативы столь же активно и все так же незаслуженно обзываются антипаттернами. :)

    Теперь к примерам.
    - DirectX. Для работы с графикой тебе необходимо по одной инстанции интерфейсов IDirect3D и IDirect3DDevice. Эти две инстанции декларируют глобальное состояние программы. Инстанции всех буферов, текстур, шейдеров и поверхностей создаются с использованием этих инстанций. Разумным будет предоставить доступ к инстанциям DirectX через подход синглтона.
    - OpenGL старых добрых версий. Процедурный интерфейс OpenGL как бы намекает на отсутствие необходимости в глобальном состоянии. Но не тут то было. Для работы с OpenGL необходимо не просто создать контекст, но еще и помнить поток, в котором этот контекст связан с поверхностью вывода. В многопоточной среде контекстов может быть несколько для параллельной загрузки ресурсов. В этом случае помнить надо уже два потока и два контекста (минимум). Само собой, в синглтоне это глобальное состояние смотрится удобнее.
    - Sockets. Не важно какие. Когда твое приложение представляет собой MMO проект и у тебя гора подсистем, постоянно и обособленно общающихся с сервером, сетевое подключение разумно оформить в виде синглтона.
    - Assets/Resources - они бывают разные, кешируемые и нет, доступные из сети, с жесткого диска, из подсистемы пререндеринга. Опять же, я несколько раз видел боль и страдания от неоднородного контроля ресурсов без соответствующей подсистемы. А сама подсистема управления ресурсами всегда централизована и лучше всего реализуется именно на синглтоне.

    Звук, ввод, многопоточный конвеер задач... вспоминать места явной необходимости синглтонов можно еще долго.
    Ответ написан
    Комментировать
  • PHP вымрет и все будет на js или без сервера все равно никак?

    gobananas
    @gobananas
    finishhim.ru
    https://vc.ru/p/2017-job-trends
    Вряд ли может умереть язык который занимает первое место + у него вышла удачная новая версия... ну по крайней мере в ближайшие 10 лет ))
    Ответ написан
    Комментировать
  • Почему в массиве иногда выпадает значение undefined?

    abyrkov
    @abyrkov
    JavaScripter
    1. Начнем с того, что while - это плохой знак. desk во внутренней функции тоже плохо, лучше использовать this
    Отрефакторим -
    var deck = {
            allCards: ["ch-6", "ch-7", "ch-8", "ch-9", "ch-10", "ch-v", "ch-d", "ch-k", "ch-t", "bu-6", "bu-7", "bu-8"],
            randomCards: [],
            randomizer: function(min, max) {
              for(var i = 0; i < this.allCards.length; i++) {
                var rand = Math.round(Math.random() * (max - min - 1));
                this.randomCards.push(this.allCards[rand]);
                this.allCards.splice(rand, 1);
            }
        }
    };
    deck.randomizer(0, deck.allCards.length);

    2. Потом мелкая ошибка в радоме - забыли прибавить min
    var deck = {
            allCards: ["ch-6", "ch-7", "ch-8", "ch-9", "ch-10", "ch-v", "ch-d", "ch-k", "ch-t", "bu-6", "bu-7", "bu-8"],
            randomCards: [],
            randomizer: function(min, max) {
              for(var i = 0; i < this.allCards.length; i++) {
                var rand = min + Math.round(Math.random() * (max - min - 1));
                this.randomCards.push(this.allCards[rand]);
                this.allCards.splice(rand, 1);
            }
        }
    };
    deck.randomizer(0, deck.allCards.length);

    3. И, наконец, ошибка логики - мы splic'им массив, значит длинна его тоже уменьшается... но рандом остается тем же - от 0 до предыдущей длины. Придется убрать min и max - с такой логикой их добавить невозможно - они будут вызывать проблемы.
    var deck = {
            allCards: ["ch-6", "ch-7", "ch-8", "ch-9", "ch-10", "ch-v", "ch-d", "ch-k", "ch-t", "bu-6", "bu-7", "bu-8"],
            randomCards: [],
            randomizer: function(min, max) {
              for(var i = 0; i < this.allCards.length; i++) {
                var rand = Math.round(Math.random() * (this.allCards.length - 1));
                this.randomCards.push(this.allCards[rand]);
                this.allCards.splice(rand, 1);
            }
        }
    };
    deck.randomizer();

    4. И, наконец, правильная логика:
    var deck = {
            allCards: ["ch-6", "ch-7", "ch-8", "ch-9", "ch-10", "ch-v", "ch-d", "ch-k", "ch-t", "bu-6", "bu-7", "bu-8"],
            randomCards: [],
            randomizer: function(min, max) {
              for(var i = 0; i < this.allCards.length; i++) {
                var rand = min + Math.round(Math.random() * ((max > this.allCards.length ? this.allCards.length : max) - min - 1));
                this.randomCards.push(this.allCards[rand]);
                this.allCards.splice(rand, 1);
            }
        }
    };
    deck.randomizer(0, deck.allCards.length);
    Ответ написан
    2 комментария
  • Нормально ли спрашивать про бывшую зарплату?

    maxaus
    @maxaus
    Вошёл вайти и пока не вышел
    Отвечайте цифру, которая немного превышает ваши ожидания - никто вашу текущую зарплату не проверит, а сами не прогадаете, т.к. у вас это, очевидно, спрашивают в 90% случаев чтобы предложить зарплату чуть больше названной цифры (если вы подходите).

    P.S.: И какой смысл думать вообще над тем, нормально это или нет, и задавать вопросы другим людям)) Ну у вас любой малознакомый человек может этот вопрос в силу своего недоразвитого воспитания задать - наверное же, вы ответите ровно столько, сколько вам удобнее, чтобы тот знал) ну или отшутитесь)
    Ответ написан
    1 комментарий