Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

WebSocket: можно ли использовать одно подключение для всего сайта?

Можно ли, установив WebSocket соединение на главной страничке сайта, продолжать пользоваться этим же соединением на всех остальных страничках? Или каждая страничка должна инициировать своё соединение? Почему-то все примеры по использованию WebSocket ограничиваются лишь одним html файлом. Пожалуйста, проясните этот момент.


Ответ

Нет, нельзя. Соединение рвётся, когда вы уходите со страницы (даже если на другую страницу того же сайта). Так что каждая страница должна инициировать соединение заново

Что такое framework и runtime?

Нигде не нашел чёткого опрделения этми двумя понятиям.
Я понимаю фреймворк, как платформу, которая необходима для работы каких-либо приложений. Например, набор динамически линкуемых библиотек для нескольких приложений - уже фреймворк. Также под это определение подохдит и Java Runtime Environment (в том числе и JVM). Однако что такое рантайм? С одной стороны это всего лишь фаза выполнения программы. С другой стороны есть куча терминов, как runtime libraries, runtime system... Что вкладывает майкрософт в это понятие тоже неясно. Объясните, пожалуйста!


Ответ

Между библиотекой и фреймворком разница небольшая, но принципиальна. Если Ваш код просто использует функции модуля, то этот модуль скорее всего библиотека. А вот если модуль заставляет Вас писать код так как он хочет и сам его вызывает, то это уже фреймворк. А вот собственно модуль - это набор файлов-исходников (иногда уже скомпилированных).
runtime - это часть кода, существует в выполнимом файле (либо в отдельных so/dll) и обеспечивает всякие "удобства". Например, узнать тип объекта или сделать те же виртуальные вызовы. Добавляется обычно компилятором и обычный пользователь может даже не знать о нем. Также словом runtime называют то время, когда программа выполняется. Что конкретно имеется ввиду - нужно сдедить за контекстом.
runtime libraries - это библиотеки, которые используются во время работы программы. Иногда библиотеки поставляются в двух видах - для разработки и для обычной работы (вторые часто оптимизированы и с них выброшено лишнее). Хороший пример - bpl файлы делфи. Для одного и того же компонента могут быть библиотеки, которые содержат всякие инструметы для IDE, а есть которые только для работоспособности кода.
JRE - это не фреймворк, это runtime библиотека. Хотя с другой стороны это фреймворк для байткода. Но так как на байткоде пищут только особые извращенцы, то обычному программисту это не фреймфорк. А вот вся java - это один сплошной фреймворк:)

Обязателен параметр Q_OBJECT при разработке под Qt?

Суть вопроса как бы вырисовывается из заголовка.
Дзен-парни, работающие часто с Qt — подскажите.


Ответ

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

Поиск по командам в linux

В играх на source есть очень удобная команда find, которая позволяет искать по всем командам и их описанию. И тут я подумал, а нет ли чего-нибудь подобного под linux?


Ответ

help
для внутренних команд оболочки (cd, echo, exit и т.д. и т.п.) есть внутренняя команда оболочки help
$ help command
если после набора help поставить пробел и нажать два раза tab, то отобразится список внутренних команд оболочки, для которых можно получить справку. начать лучше с:
$ help help

man
многие программы/команды/функции имеют т.н. man-страницу с детальным описанием аргументов/опций/клавиатурных сокращений для запуска/использования. просмотреть их можно с помощью программы man
$ man zip
если после набора man поставить пробел и нажать два раза tab, то отобразится список man-страниц, которые можно почитать. начать лучше с:
$ man man
apropos
программа apropos позволяет искать по заголовкам и кратким описаниям man-страниц ключевые слова. например:
$ apropos reboot

info
программы, разрабатываемые в рамках проекта gnu, обычно имеют документацию в формате texinfo, к которой можно обратиться с помощью программы info
$ info gcc
если после набора info поставить пробел и нажать два раза tab, то отобразится список доступных руководств. начать лучше с:
$ info info
info -k
с помощью опции -k ключевые слова можно искать документацию, содержащую любое из перечисленных ключевых слов. а если заключить строку в кавычки, будет производиться поиск именно этой строки:
$ info -k "regular expressions" ... "(sed)Invoking sed" -- Extended regular expressions, choosing ...
затем можно просмотреть найденный документ:
$ info "(sed)Invoking sed"

опция -h
многие программы имеют «встроенную» справку, выдаваемую при вызове этой программы с опцией -h (--help):
$ firefox -h

Фигурные скобки в Java. Что происходит когда я опускаю скобки?

Есть один вопрос касаемо Java. Что происходит, когда я опускаю скобки как в примере ниже:
Без скобок:
for(...) someAction() ;
идентичный код со скобками:
for(...) { someAction() ; }
Использование или неиспользование скобок в этом примере как-то влияет на время компиляции или производительность ?


Ответ

Разница в том, что без скобок будет выполняться только одна строка, следующая после цикла/условия/пр. В случае со скобками будет выполнено все внутри { }. Если Вы на 99.9% уверены, что конструкция будет неизменна - можете писать без скобок. Чтобы не было впоследствии ситуации, что добавите еще 1 строчку, скобки забудете, а затем программа не так отработает.

Сколько занимает элемент массива в памяти?

Объясните мне пожалуйста одну простую вещь.
long unsigned int = 4 байта. 1024 * 1024 * long unsigned int = 4 мегабайта.
Почему же массив, наполненный числами от 0 до 1024 * 1024 занимает в памяти 40 мегабайт? (в php еще в два раза больше). Я понимаю, у каждого элемента есть там индекс, указатели какие-то, но хочу не понимать, а четко знать, куда моя память тратится?
По просьбе трудящихся прикладываю код:
var i = 1024 * 1024, arr = []; while(i--) arr.push(i);
По просьбе трудящихся прикладываю скрины:
Win 7:
Win 8:
Ubuntu (как это интерпретировать я хз, но кому интересно вот):
P.S. Из чего вообще возник этот вопрос - у меня есть около 3кк ip адресов, которым надо в соответствие поставить 3кк неких id. Но на это уходит почти гигабайт этой самой памяти (два массива по три миллиона чисел или объект с ключом-значением, разница небольшая), тогда как csv-файлик со двумя столбцами этих чисел весит всего 30мб.


Ответ

Для начала, не стоит в языках со сборкой мусора пытаться что-либо связанное с внутренним устройством памяти замерить снаружи. RSS - объем ОП, который занимает сам процесс ноды, с тем, сколько реально "занято", а сколько "прозапас" коррелирует слабо.
В частности, нода, очень любит кушать память. Пока система дает ей оперативную память, она будет ее запрашивать, если происходит много аллокаций. Сделано это прежде всего для скорости работы.
Как верно заметил Artur Udod в комментарии, в javascript, согласно стандарту, все числа - 64х битовые, т.е. 8 байт на число.
Чтобы замерить правильно размер 1 элемента массива - необходимо снимать хипдамп, искать там нужный объект и смотреть, а сколько же реально места там занято.
Есть вариант грубого замера. Для этого - запускаем node --expose-gc. Данный флаг позволяет принудительно инициировать отчистку мусора.
Посредством нехитрых вычислений вида:
var a = []; var memBefore = 0; var memAfter = 0; var length = 1000000;
gc(); memBefore = process.memoryUsage().heapUsed; (function(len){ for(var i = 0; i < len; i++){ a[i] = i; } })(length); gc(); memAfter = process.memoryUsage().heapUsed; console.log('Memory used by 1 element is:', (memAfter - memBefore) / length);
Получим примерный размер элемента массива в памяти. Тут следует учитывать, что будет погрешность в большую сторону, т.к. REPL на разбор запросов тоже будет кушать память. Причем из той же кучи.
Замерил хип дампом, через аллокацию массива с 100к элементов:

Здесь - 8,53 байта на элемент массива. Однако, стоит помнить, что сам массив тоже занимает память.
В целом, Mike верно подметил, внутреннее устройство, действительно сильно зависит от версии движка, с этим ничего не поделаешь.
Еще один забавный момент заключается в том, что внутреннее устройство массива в V8 сильно зависит от его размера и структуры. К примеру в node версии 5.7.1 массив на 810 312 элементов "весит" значительно больше (примерно 12 байт на элемент), чем на 810 311 элементов (8,004 байта), это уже привет внутреннему устройству движка, вполне возможно, что он просто превращает массив в словарь, тут уже гадать не буду, однако с дальнейшим ростом, "размер" элемента массива опять падает.

Странное поведение Javascript при передаче объекта по ссылке

Написал простой пример с изменением объекта в функции при передаче по ссылке. https://plnkr.co/edit/kR9zRc0Y...
var salaries = { "Вася": 100, "Петя": 300, "Даша": 250 };
function changeObject(object) { for (var key in object) { object[key] += 100; } }
console.log(salaries); changeObject(salaries); console.log(salaries);
В итоге результат:
Object {Вася: 100, Петя: 300, Даша: 250} Object {Вася: 200, Петя: 400, Даша: 350}
Передача по ссылке происходит, но console.log() отрабатывает не так как ожидается, как будто Chrome (Version 49.0.2623.110 (64-bit)) фиксирует состояние объекта на момент console.log(), хотя вроде должен ссылаться на один и тот же измененный объект.
Кто знает в чем может быть дело?


Ответ

Суть заключается в том, как работает консоль в хроме. И конкретно, функция log
Она выводит значение объекта в момент вывода, при этом, если для вывода всех свойств требуется много места, появляется возможность развернуть объект.

При этом можно заметить, что в свернутом виде будет показываться информация актуальная на момент вывода, но если развернуть

будет показано состояния объекта на момент разворачивания.
Чтобы избежать такой неоднозначности, можно использовать
console.dir

Основы JavaScript, копия объектов

Я заметил, что если есть какой-то объект, и если создать новый, присвоив ему значение этого объекта, и поменять в нем какое-то поле, то в старом оно тоже поменяется:
var a = {prop: 1}; document.getElementById("1").textContent = a.prop + ''; var b = a; b.prop = 2; document.getElementById("2").textContent = a.prop + '';


Какие есть способы создать копию объекта? То есть, чтобы изменения новой переменной не влияли на старую.


Ответ

Весь смысл в том, что в Javascript все объекты присваиваются по ссылке без исключений, это означает, что скольким бы переменным вы не присвоили объект, он всегда будет оставаться в памяти в единственном числе.
var a = {prop: 1} var b = a; var c = b; (c===b&&b===a&&c===a) // true
Пока хоть одна переменная ссылается на объект, он продолжает существовать. Когда последняя переменная, ссылающаяся на объект удаляется, удаляется и сам объект.
var a = {prop: 1}; var b = a; a.prop = 2; delete a; (b.prop===2); // true
В javascript нету оператора, позволяющего сделать копию объекта, поэтому копирование объектов в Javascript сводится к созданию нового с точно такими же свойствами, как у первого.
var a = {prop: 1}; var b = {}; b.prop = a.prop;
Однако нужно учитывать тот факт, что свойство объекта может содержать другой объект, который так же будет передан по ссылке, в случае присваивания, поэтому следующий пример создаст не правильный клон:
var a = { prop: { sub: 1 } } var b = {}; b.prop = a.prop;
Потому что свойство sub будет одним и тем же для обоих объектов.
a.prop.sub = 2; (b.prop.sub===1) // False
Поэтому при создании копии объекта необходимо проверять не являются ли его свойства объектами, и в этом случае производить с ними ту же операцию, что и мы провернули с a и b.
В целом функция создания клона объекта будет выглядеть так:
function makeClone(obj) { let clone = {}; // Создаем новый пустой объект for (let prop in obj) { // Перебираем все свойства копируемого объекта if (obj.hasOwnProperty(prop)) { // Только собственные свойства if ("object"===typeof obj[prop]) // Если свойство так же объект clone[prop] = makeClone(obj[prop]); // Делаем клон свойства else clone[prop] = obj[prop]; // Или же просто копируем значение } } return clone; }
Однако эта функция не универсальна и сработает правильно не во всех случаях, так как в Javascript помимо простых объектов, есть так же встроенные объекты и объекты созданные из прототипов, которые уже не получится просто так взять и скопировать. Это экземпляры Image, Date, HTMLElement, кастомные классы и пр. Кроме того бывают случаи когда вложенные свойства содержат ссылки на объекты, косвенно возвращающие нас к самим же себе. Например:
var a = {}, b = {prop: a}; a.prop = b;
Если вы запустите функцию makeClone для переменной а, то процесс создания клона будет происходить бесконечно, что вызовет "Maximum call stack size exceeded". Так что существует очень много нюансов клонирования объекта, поэтому лучше не изобретать велосипед, а воспользоваться готовыми решениями такими как jQuery.extend:
var a = {prop: 1}; var clone = jQuery.extend(true, {}, a);
Кроме того stand-alone аналоги этой функции можно найти на npmjs.
ЗЫ: По поводу Object.assign - это экспериментальный метод и пока он не поддерживается браузерами, и кажется babel без специальных плагинов его тоже не воспринимает.

Можно ли добавить требование обязательного указания номера issue при пуше в гит?

На гитхабе есть удобная штука: пишешь комментарий к коммиту, указываешь номер issue - и они связаны после пуша. Например:
Добавлено логирование конвертаций. #50
Другое дело, что я иногда забываю проставить этот номер, хотелось бы какую то проверку прикрутить, скорее на стороне сервера, но можно и локально.
Вопрос - есть ли готовые решения?
Если нет - а как это можно сделать?


Ответ

(погуглить использование гитхуков), но я отвечу о минусах подхода "правильный коммит-месседж на сервер-сайде"
на стороне сервера - не надо. если ты заставишь кодеров добавлять обязательные сообщения к коммиту, рано или поздно кто-нибудь сделает 120 коммитов локально, потом окажется, что один из коммитов (допустим, первый), прокомментирован неправильно.
закомитить нельзя. придется звонить/писать/ставить тикет тебе.
тебе посоветуют сделать rebase. rebase не сработает, потому, что кто-то выше по дереву изменил структуру каталогов.
это трата времени. если хочешь энфорсить комменты, делай это на клиенте, чтобы человек, которому нужно что-то запушить _важное_и_срочное_ (такое бывает в продакшене боевом), мог сделать git commit --no-verify
P.S. серверный гитхук, который не запрещает пушить, но сам проставляет номер патча или другую инфу полезную - это вполне ок.

Получение элемента с другого сайта

В div сайта example1.ru нужно вставить div с сайта example2.ru
Написал такой код, но он почему-то не работает. В чем может быть проблема?


$("#vip_view_div_cross").load("example2.ru #vip_view_div");


Ответ

getElement('http://ru.stackoverflow.com', '#nav-questions', function(element) { console.log(element); }); getElement('http://ru.stackoverflow.com', '.question-hyperlink', function(element) { console.log(element.innerHTML); }); function getElement(url, selector, c) { request(new XMLHttpRequest()); function request(xhr) { xhr.open('GET', 'https://crossorigin.me/' + url, true); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status == 200) { html = document.createElement('div'); html.innerHTML = xhr.responseText; c(html.querySelector(selector)); } } } } }
jquery
$('#q').load('https://crossorigin.me/http://ru.stackoverflow.com #nav-questions');


Можно ли создать класс-обертку для асинхронизации методов?

Допустим у нас есть класс внутри которого много синхронных методов:
public class A { public int Return5() => 5;
public string ReturnString() => "string"; }
Можно ли создать класс обертку для асинхронизации синхронных методов? Тоесть чтобы на каждый синхронный метод создавался такой же только с возвращаемым типом Task<> и вконце названия метода добавлялось окончание Async. Допустим чтобы это выглядело так:
var asyncA = new AsyncClass;
var result = await asyncA.ReturnStringAsync();


Ответ

Технически можно, но это обычно не нужно.
Если узкое место у метода — потребление процессора, лучше выставить синхронный интерфейс. Тогда клиенты могут легко запустить задание асинхронно сами:
var five = await Task.Run(() => a.Return5());
А могут и не запускать асинхронно, если методу это не нужно.
То есть в этом случае просто выставляйте синхронный метод, клиенты сами могут легко превратить его в асинхронный.

А вот если же метод не занимает поток для своего выполнения (например, он грузит что-нибудь из интернета, пользуясь async-функциями), тогда нужно выставлять только асинхронный метод. Соответственно вы не сможете выставлять синхронный метод, разве что искусственно создать его через Task.Wait() (что снова-таки не нужно, ведь клиент при желании может сделать это сам).

Дополнительное чтение по теме от одного из ключевых разработчиков асинхронных фич C#: Should I expose synchronous wrappers for asynchronous methods?

Как технически сделать асинхронную обёртку? Например, через Task.Run
public class AsyncA { private A a = new A(); public Task Return5Async() => Task.Run(() => a.Return5()); // и т. д. }

Symfony 3 деплой и развертывание проекта на сервере

Какой способ лучше всего подходит для деплоя symfony3 проекта? Как это сделать по чистому ftp? Прогуглив, наткнулся на Capifony, но по идеи он не работает с третьей версией symfony.


Ответ

1.Вариант
Symfony Deployment Basics
Типичные шаги при развертывании приложения Symfony включают в себя:
Вы можете добавить свой код на сервер используя какой нибудь FTP клиент.Например FileZilla Установите ваши зависимости для vendor (как правило, делается с помощью Composer и может быть сделано перед загрузкой). Запуск миграции базы данных или аналогичные задачи по обновлению структуры изменения данных. Очистка кэша.
Развертывание может также включать в себя другие задачи, такие как:
Пометка определенную версию вашего кода в качестве выхода в репозитории управления исходными кодами Создание временного плацдарма для построения настроек обновлений "в автономном режиме - offline" Выполнение каких-либо тестов, доступных для обеспечения кода и / или стабильность работы сервера Удаление любых ненужных файлов из web/directory, чтобы сохранить производственную среду,то бишь environment в чистоте. Очистка внешних систем кэш-памяти (как Memcached или Redis).
2.Вариант
Все это сделать локально а потом с помощью Source Control (GitTortoise) залить на сервер.
3.Вариант
Есть также инструменты, чтобы помочь облегчить "боль" развертывания. Некоторые из них были специально адаптированы к требованиям Symfony.
http://symfony.com/doc/current/cookbook/deployment/tools.html#using-build-scripts-and-other-tools

Rails 4.2.6. - Как создать миграцию с Хранимыми процедурами?

Всем привет! Как создать хранимые процедуры в миграциях? Спасибо.
Рабочий код:
DELIMITER | DROP PROCEDURE IF EXISTS search_result | CREATE PROCEDURE search_result(IN search_data VARCHAR(255))
BEGIN DROP TABLE IF EXISTS searchTableRes; CREATE TABLE IF NOT EXISTS searchTableRes ( `id` INT NOT NULL, `title` VARCHAR(255), `article` TEXT, `articleable_id` INT, `articleable_type` VARCHAR(255) )ENGINE=MYISAM SET utf8 COLLATE utf8_general_ci;
INSERT INTO searchTableRes ( `id`, `title`, `article`, `articleable_id`, `articleable_type` )
SELECT `a`.`id` as `id`, `a`.`title` as `title`, `a`.`article` as `article`, `a`.`articleable_id` as `articleable_id`, `a`.`articleable_type` as `articleable_type` FROM `articles` `a`;
CREATE FULLTEXT INDEX ixFull ON searchTableRes (`title`, `article`); SELECT *,MATCH(`title`, `article`) AGAINST (CONCAT('*',search_data,'*') IN NATURAL LANGUAGE MODE) AS coefficient FROM searchTableRes WHERE MATCH(`title`, `article`) AGAINST (CONCAT('*',search_data,'*') IN BOOLEAN MODE) ORDER BY coefficient DESC; ALTER table searchTableRes ENGINE = BLACKHOLE; END | DELIMITER ;


Ответ

Вы можете воспользоваться ActiveRecord::Base.connection.execute() для выполнения чистого SQL-запроса. Можно поступить примерно так
class CreateProcedure < ActiveRecord::Migration def change sql = 'DROP PROCEDURE IF EXISTS search_result'; ActiveRecord::Base.connection.execute sql sql << 'CREATE PROCEDURE search_result(IN search_data VARCHAR(255))
BEGIN DROP TABLE IF EXISTS searchTableRes; CREATE TABLE IF NOT EXISTS searchTableRes ( `id` INT NOT NULL, `title` VARCHAR(255), `article` TEXT, `articleable_id` INT, `articleable_type` VARCHAR(255) )ENGINE=MYISAM SET utf8 COLLATE utf8_general_ci;
INSERT INTO searchTableRes ( `id`, `title`, `article`, `articleable_id`, `articleable_type` )
SELECT `a`.`id` as `id`, `a`.`title` as `title`, `a`.`article` as `article`, `a`.`articleable_id` as `articleable_id`, `a`.`articleable_type` as `articleable_type` FROM `articles` `a`;
CREATE FULLTEXT INDEX ixFull ON searchTableRes (`title`, `article`); SELECT *,MATCH(`title`, `article`) AGAINST (CONCAT('*',search_data,'*') IN NATURAL LANGUAGE MODE) AS coefficient FROM searchTableRes WHERE MATCH(`title`, `article`) AGAINST (CONCAT('*',search_data,'*') IN BOOLEAN MODE) ORDER BY coefficient DESC; ALTER table searchTableRes ENGINE = BLACKHOLE; END'; ActiveRecord::Base.connection.execute sql end end

Ссылка на функцию внутри функции

В Python любая функция - это объект. Но как тогда получить ссылку на этот объект внутри функции? Никакого self функция внутри себя не видит.


Ответ

А что мешает использовать имя функции?
>>> def foo(): ... return foo ... >>> foo() >>> foo
Если имя функции неизвестно, то получить его нельзя. Подобая функциональность была отвергнута
Но, как говорится, если очень хочется, то есть несколько вариантов. Я бы не рекомендовал так делать без особой на то нужды
Через inspect
import inspect
def foo(): print inspect.stack()[0][3]
Через sys
import sys
def foo(): print sys._getframe().f_code.co_name
Получить метод, зная название функции, можно через функцию globals()
Upd
Внимание! Согласно документации не все реализации python могут включать sys._getframe. Это функция для внутреннего использования интерпретатора CPython и может не работать на других. Используйте на свой страх и риск

Вызов функции-члена из лямбда-функции

Есть класс, в котором два метода. Один - public, второй - private. В public-методе создаю лямбду и хочу вызвать в ней private метод класса.
Как это можно сделать?


Ответ

Достаточно передать this в область захвата лямбды:
#include
struct S { void g() { std::cout << "public
"; auto l = [this]() { std::cout << "lambda
"; f(); }; l(); } private: void f() { std::cout << "private
"; } };
int main() { S s; s.g(); }
Тест

Linux, PHP: не изменяется значение «sendmail_path»

Беру php.ini
sudo vim /etc/php/7.0/cli/php.ini Изменяю ;sendmail = на sendmail = Сохраняю изменения. Перегружаю сервер:
sudo service apache2 restart Перехожу на мой phpinfo()
http://test/php/info.php Значение sendmail_path не изменилось:
/usr/sbin/sendmail

В чём может быть причина?


Ответ

Причина в том, что вы изменяете конфигурацию для PHP-клиента, а не модуля Apache. Вам нужно изменить соответствующее значение в следующем файле:
sudo vim /etc/php/7.0/apache2/php.ini

Замена NULL на значение предыдущего значения

Делаю такой запрос на t-sql:
SELECT *, CASE WHEN Sum_ IS NOT NULL THEN Sum_ ELSE COALESCE(Sum_, 0) END AS first_Non_Null FROM dbo.VIEW_1; GO
Где идет обработка поля Sum_, если оно пустое, то заменяем его на 0, в противном случае оставляем без изменения. У меня вопрос такой, можно сделать так, чтобы сделать вставку не 0, а значения предыдущего числового значения.
Если, допустим, данный запрос вернет:
Index_data | Sum_ _____________________ 20.10.2015 | 8 21.10.2015 | 2 22.10.2015 | NULL 23.10.2015 | 5 24.10.2015 | NULL 25.10.2015 | NULL 26.10.2015 | 6
Переделать его так:
Index_data | Sum_ _____________________ 20.10.2015 | 8 21.10.2015 | 2 22.10.2015 | 2 23.10.2015 | 5 24.10.2015 | 5 25.10.2015 | 5 26.10.2015 | 6
Как это сделать? Хотел курсором перебрать, однако, хочется оформить это просто запросом или вложенными запросами.
SELECT *, CASE WHEN Sum_ IS NOT NULL THEN Sum_ ELSE COALESCE(Sum_, SELECT Sum_ FROM dbo.VIEW_1 WHERE ????) END AS first_Non_Null FROM dbo.VIEW_1; GO
или как-то так:
DECLARE @val nvarchar(30); SELECT *, CASE WHEN Sum_ IS NOT NULL THEN Sum_ ELSE COALESCE(Sum_, Sum_.PREV....... ) END AS first_Non_Null FROM dbo.VIEW_1; GO
Такое возможно сделать?


Ответ

Используйте функцию LAG
SELECT index_data, coalesce(Sum_, LAG(Sum_) OVER(ORDER BY index_data)) FROM dbo.VIEW_1;

MySQL: GROUP BY устовия для COUNT(*)

Как задать максимальный и минимальный размеры группы, чтобы получить записи, где count < 5 и count > 2?
На данный момент использую такой запрос:
SELECT id, info, COUNT(*) as count FROM notification GROUP BY info ORDER BY count DESC;
Пример:
+----+-------+ | id | info | +----+-------+ | 1 | Admin | | 2 | User | | 3 | User | | 4 | User | | 5 | User | | 6 | User | | 7 | Admin | | 8 | Admin | | 9 | Test | | 10 | Test | +----+-------+
Желаемый вывод:
+----+-------+--------+ | id | info | count | +----+-------+--------+ | 1 | Admin | 3 | +----+-------+--------+


Ответ

Используйте параметр HAVING
SELECT id, info, COUNT(*) as count FROM notification GROUP BY info HAVING count(*) > 2 and count(*) < 5 ORDER BY count DESC;
Пример на sqlfiddle

GitHub: Разрешить push для репозитория

Возможно, я что-то не понимаю, но как разрешить изменять свой репозиторий другим пользователям? Разве любой юзер гихаба не сможет скопировать мой репозиторий, внести изменения и сделать push? Если нет, то как хотя бы разрешить определенным пользователям изменять... вообщем, ка это все работает? :(


Ответ

Разве любой юзер гихаба не сможет скопировать мой репозиторий
Может. Если он публичный, конечно.
внести изменения
Может. Локально. Файлы ж после клонирования у него на диске, он может делать что хочет.
и сделать push
Не может. Да и сами подумайте, многие крупные проекты хостятся на гитхабе, как весело было бы, если бы изменения в них мог пушить кто угодно?
Если хотите кому-то разрешить пушить в свой репозиторий, вам нужно добавить его в настройках репозитория в Collaborators
Но для публичных репозиториев в этом обычно нет необходимости, т. к. другие могут пушить свои изменения в собственные копии (форки) (каждый может создать свой одним нажатием кнопки Fork наверху), а потом предлагать сам стянуть (pull) изменения из них (pull request).

Есть ещё вопрос лицензий, но это долгая история.

Как создать динамический массив?

Хочу разобраться с динамическим выделением памяти в c. Пришла в голову идея, попробовать сделать программу, которая спрашивает у пользователя имя и записывает ввод в массив типа char, но так чтобы массив сам выделял себе память. То есть без предварительного выделения вида char name[30] = {0};. Я ввожу имя Магомед и массив сам выделяет себе память на 7 символов. Как это сделать?


Ответ

Я бы взял указатель, длину и зарезервированную длину. Примерно
char * s = malloc(16); int size = 16; int used = 0;
И дальше читаем по одному символу. Как только вносим его в s, тут же увеличиваем used; как только used == size, так сразу увеличиваем массив раза в два:
s = realloc(s,size *= 2);
И все. Мы всегда знаем, сколько места имеется, сколько занято. Как в векторе в C++.

Как сделать приложение одиночка?

Как сделать приложение одиночка средствами Qt5+ под Windows (xp, 7, 8, 10) ? Чтобы нельзя было запустить два экземпляра одновременно.


Ответ

Файл блокировки
Файл будет удалён автоматически Каждый пользователь может запустить свою версию.
#include #include #include #include
QString tmpDir = QDir::tempPath(); QLockFile lockFile(tmpDir + "/.lock");
if(!lockFile.tryLock(100)){ QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("You already have this app running." "
Only one instance is allowed."); msgBox.exec(); return 1; }
Семафоры и разделяемая память
Уникальный инстанс приложения на всю машину
QSystemSemaphore sema("", 1); sema.acquire();
#ifndef Q_OS_WIN32 // в Unix разделяемая память не чистится при креше // Очищаем, если осталась от предыдущих запусков QSharedMemory nix_fix_shmem(""); if(nix_fix_shmem.attach()){ nix_fix_shmem.detach(); } #endif
QSharedMemory shmem(""); bool is_running; if (shmem.attach()){ is_running = true; }else{ shmem.create(1); is_running = false; } sema.release();
if(is_running){ QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("You already have this app running." "
Only one instance is allowed."); msgBox.exec(); return 1; }

Замена HDD RAID 1 на более ёмкий HDD [ubuntu]

Есть система Ubuntu 16.04 которая стоит на Software Raid 1. Какими способами можно заменить все HDD в RAID 1 на более ёмкие? Короче говоря, нужно перенести систему с Software RAID 1 160G на Software RAID 1 500G.


Ответ

Рейд вероятно собран через linux raid, более известный как mdadm
Если есть возможность все 4 диска сразу подключить, то подключаете все диски, размечаете как необходимо. Затем расширяете массив на все 4 диска, raid1 можно без проблем менять число дисков в массиве.
mdadm /dev/mdX -a /dev/sdcX mdadm /dev/mdX -a /dev/sddX mdadm --grow /dev/mdX -n 4
Ждёте окончание синхронизации. После этого убираете старые диски и сужаете массив обратно до 2 дисков.
mdadm /dev/mdX -f /dev/sdaX mdadm /dev/mdX -r /dev/sdaX mdadm /dev/mdX -f /dev/sdbX mdadm /dev/mdX -r /dev/sdbX mdadm --grow /dev/mdX -n 2
Всё, массив теперь живёт на новых дисках, стрые диски можно физически отключать. Теперь можно сказать mdadm, что надо увеличить размер массива командой
mdadm --grow /dev/mdX --size=max
Дальнейшие действия в зависимости от того, что на массиве расположено. Если файловая система - то смотря какая файловая система: xfs_growfs, resize2fs или что-то другое. Если LVM - то командой pvresize можно сказать, что размер устройства изменился.
Если есть возможности подключить только два диска - то поочерёдно отключаете один старый, добавляете один новый, ждёте синхронизацию массива, отключаете второй старый диск, ставите второй новый. Затем продолжаете с --grow --size=max. Расширить массив на новые диски и только после синхронизации вынимать старые немного надёжнее для пограничного случая, когда вынули 1 диск, а при синхронизации с новым оставшийся старый диск неожиданно помер.

C# различие List и Collection

В чем различие между List и Collection. Где и при каких условиях будет рациональнее использовать тот или другой тип?


Ответ

Разница в том, что в Collection есть ряд виртуальных методов (InsertItem, RemoveItem, SetItem, ClearItems), которые вы можете переопределить в классе-наследнике по своему усмотрению, и тем самым задать этим наследникам своё поведение при вставке, удалении или очистке элементов. При этом класс List в большей степени сосредотачивается на быстродействии при выполнении операций вставки/удаления/очистки, нежели на предоставлении пользователю средств расширяемости в классах-наследниках (виртуальных членов у него нет вовсе).
MSDN нам авторитетно заявляет, что
Provides the base class for a generic collection
Иными словами, класс Collection в первую очередь предназначен для создания на его базе собственных обобщённых коллекций, тогда как List "для работы"

margin-left для полосы прокрутки в Chrome

Имеется полоса прокрутки:
#parent { height: 200px; width: 300px; overflow-y: auto; } #child { height: 500px; width: 100%; background: teal; } ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #f6f5f3; } ::-webkit-scrollbar-thumb { background: #c1c1c1; }


Хочу сделать, чтобы между полосой прокрутки и контентом (блок #child) было расстояние в 2px. По сути хочу написать ::-webkit-scrollbar { margin-left: 2px; }. Так не работает. Пробовал добавить padding-right: 2px к элементу #parent, но тогда если полосы прокрутки нет (то есть в блоке #child мало содержимого (в примере высота #child фиксирована, но в реальном проекте зависит от содержимого)), то будут лишние 2px пустого места. Как добавить расстояние 2px между полосой прокрутки и блоком #child?
Обновление:
У блока #parent имеется свойство overflow-y: auto;. То есть появится полоса прокрутки или нет зависит от высоты блока #child. В примере высота #child фиксирована, однако в реальном проекте зависит от содержимого (там динамически подгружаемый текст, много текста => появится полоса прокрутки, мало текста => не появится). Это всё к тому, что если полосы прокрутки нет, то решение не должно влиять на отображение. То есть хочется добавить 2px свободного места между контентом и полосой прокрутки, если полоса прокрутки есть, и ничего не добавлять, если её нет.


Ответ

#parent { height: 200px; width: 300px; overflow-y: auto; } #child { height: 500px; background: teal; } ::-webkit-scrollbar { width: 10px; // 8px (ширина полосы прокрутки) + 2px (расстояние между полосой прокрутки и контентом) } ::-webkit-scrollbar-track { background: #f6f5f3; } ::-webkit-scrollbar-thumb { background: #c1c1c1; border-left: solid 2px #fff; }


Какой уровень доступа получат переменные?

объясните записи
1:
Object obj = new Object() { Integer id = 10; String name = "name"; };
2:
Object obj = new Object() { { Integer id = 10; String name = "name"; } };
в чем разница между этими записями? в какую область видимости попадут переменные и какие модификаторы доступа они получат?


Ответ

Вы создаёте экземпляр анонимного класса, который является наследником класса Object с двумя новыми полями. Так как эти поля объявлены без модификаторов доступа, то они получат модификаторы доступа по умолчанию. Можно будет обращаться к этим полям как obj.id и obj.name Вы создаёте экземпляр анонимного класса, который является наследником класса Object. Новых полей у этого класса нет, но есть так называемый Instance initialization block. Это такой блок, который будет выполнен при каждом создании экземпляра класса. Можно считать, что код внутри этого блока будет скопирован в начало каждого конструктора. Таким образом, переменные, объявленные внутри этого блока, являются обычными локальными переменными, и исчезнут после выхода из блока.

Фотогалерея на bootstrap для изображений разных размеров

Делаю страничку, на которой пользователи заливают картинки, а потом эти картинки отображаются в слайдере. Картинки оказываются разных размеров и с разными расширениями, из-за чего слайдер при смене изображения либо меняется в высоте если картинка большая, либо становиться виден серый фон слайдера если картинка маленькая. Как можно сделать, чтобы слайдер не менялся в размерах при смене изображения, а все картинки растягивались по всему слайдеру? Естественно, нужно, чтобы адаптивность слайдера не была потеряна.


Ответ

Попробуйте плагин фоторама. Все картинки разных размеров.




Насколько оптимальна работа с System.Linq?

Волнует вопрос оптимальности работы с LINQ. Один знакомый уверял меня, что когда я вызываю .ElementAt(N), то за сценой происходит нечто подобное:
public static T ElementAt(this IEnumerable Data, int Index) { if (Index < 0) throw new ArgumentOutOfRangeException(); int i = 0; foreach(T x in Data) if (i++ == Index) return x; throw new ArgumentOutOfRangeException(); }
Как мы понимаем, эту куда медленнее, чем просто получить элемент по индексу в том же массиве, листе и прочем. Если это действительно так, и
a[999]; // int[] a = new int[1000];
отработает в ~1000 раз быстрее, чем
a.ElementAt(999);
то возможно ли создать метод-расширение для всех классов, у которых гарантировано есть индексатор?


Ответ

Это не совсем так. Почти все методы LINQ сначала делают проверку на список. Но если ты и так знаешь, что там список, то используй скобки, а не LINQ. Они же даже короче.
public static TSource ElementAt(this IEnumerable source, int index) { if (source == null) throw Error.ArgumentNull("source"); IList list = source as IList; if (list != null) return list[index]; if (index < 0) throw Error.ArgumentOutOfRange("index"); using (IEnumerator e = source.GetEnumerator()) { while (true) { if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index"); if (index == 0) return e.Current; index--; } } }

Нумерованый список и под список

Есть нумерованный список который начинается с "1". Нужно сделать так чтобы под список начинался с цифры- с которой начинается родительский элемент.
Возможно ли сделать такое средствами css без js?
.list { color: $color-primary; font-weight: 600; & > li { &:before { margin-right: 1.2rem; } ul { color: $color-minor-dark; li { &:before { margin-right: 1.2rem; } } } } &.numeration { counter-reset: list decimal; & > li { list-style-type: none; &:before { counter-increment: list; content: counter(list) "."; color: $color-active; } ul { counter-reset: list decimal; & > li { &:before { counter-increment: lists; content: counter(lists) "." counter(decimal); } } } } } &.sm { font-size: 1.4rem; & > li { & + li { margin-top: 1.2rem; } ul { margin-top: 1.2rem; margin-left: 1.6rem; & > li { margin-top: 1.2rem; padding-left: 1.2rem; } } } } &.md { font-size: 1.6rem; & > li { & + li { margin-top: 1.4rem; } ul { margin-top: 1.4rem; margin-left: 1.6rem; & > li { margin-top: 1.4rem; padding-left: 1.2rem; } } } } }

  • work status
  • annual income
  • net worth
    • forex market
  • position 5


Ответ

ol { /* убираем стандартную нумерацию */ list-style: none; /* Идентифицируем счетчик и даем ему имя li. Значение счетчика не указано – по умолчанию оно равно 0 */ counter-reset: li; } li:before { /* Определяем элемент, который будет нумероваться — li. Псевдоэлемент before указывает, что содержимое, вставляемое при помощи свойства content, будет располагаться перед пунктами списка. Здесь же устанавливается значение приращения счетчика (по умолчанию равно 1). */ counter-increment: li; /* С помощью свойства content выводится номер пункта списка. counters() означает, что генерируемый текст представляет собой значения всех счетчиков с таким именем. Точка в кавычках добавляет разделяющую точку между цифрами, а точка с пробелом добавляется перед содержимым каждого пункта списка */ content: counters(li,".") ". "; }

  1. пункт
  2. пункт
    1. пункт
    2. пункт
    3. пункт
      1. пункт
      2. пункт
      3. пункт
    4. пункт
  3. пункт
  4. пункт

Регулярное выражение для поиска непоследовательных дубликатов слов

([[a-zа-я|А-Я]+)([[:space:]]+)\1
Данное регулярное выражение позволяет найти в тексте дубликаты слов, которые следует друг за другом. Например: "Что мне мне делать". Но каким должно быть регулярное выражение, если я хочу найти непоследовательно повторяющиеся слова?


Ответ

Можно воспользоваться следующим выражением:
SELECT * FROM regexTest WHERE REGEXP_LIKE( test, '([^_a-zA-Z0-9а-яА-ЯёЁ]|^)([a-zA-Zа-яА-ЯёЁ]+)[^_a-zA-Z0-9а-яА-ЯёЁ].*\2', 'i')
См. демо регулярного выражения
Подробности
([^_a-zA-Z0-9а-яА-ЯёЁ]|^) - Захватываемая подмаска №1 (в регулярках Oracle нет поддержки незахватываемых групп): любой 1 символ, отличный от английских и русских букв, цифр и знака подчёркивания ([^_a-zA-Z0-9а-яА-ЯёЁ]) или (|) начало строки (^) ([a-zA-Zа-яА-ЯёЁ]+) - Захватываемая подмаска №2: 1 и более английских или русских букв [^_a-zA-Z0-9а-яА-ЯёЁ] - любой 1 символ, отличный от английских и русских букв, цифр и знака подчёркования .* - 0 и более любых символов, отличных от знака перевода на новую строку (если использовать модификатор n (т.е. третий аргумент должен быть 'in'), можно найти повторяющиеся слова на разных строчках строки) \2 - обратная ссылка на значение захватываемой подмаски №2.
См. SQL-демо
CREATE TABLE regexTest( test varchar2(50));
INSERT INTO regexTest VALUES ('Что мне тут мне делать'); INSERT INTO regexTest VALUES ('Что мне мне делать'); INSERT INTO regexTest VALUES ('Что тут мне делать'); INSERT INTO regexTest VALUES ('Что делать? Дела?'); INSERT INTO regexTest VALUES ('Дела,дела...'); INSERT INTO regexTest VALUES ('Ничего-ничего, так себе...'); COMMIT;
SELECT * FROM regexTest WHERE REGEXP_LIKE(test, '([^_a-zA-Z0-9а-яА-ЯёЁ]|^)([a-zA-Zа-яА-ЯёЁ]+)[^_a-zA-Z0-9а-яА-ЯёЁ].*\2')
Результат:
TEST Что мне тут мне делать Что мне мне делать Дела,дела... Ничего-ничего, так себе...
Флаг 'i' позволяет находить повторяющиеся слова в разных регистрах. Если его убрать, будут найдены только 2 результата:
Что мне тут мне делать Что мне мне делать

Регулярное выражение. Как найти числа между пробелами без самих пробелов?

Как найти все числа от 5 до 10 знаков включительно, которые находятся между пробелами или концом/началом строки? Нужно найти именно числа, без пробелов.
Например:
181523539532037 52844 072 301 - должно найти только 52844
BIC 55555 77777 9999999 554664 - должно найти 55555 77777 9999999 554664
123456 - если в строке нет ничего, кроме 123456, то найти должно 123456
Я не силён в регулярных выражениях, попробовал \D\d{5,10}\D, но, во-первых, оно включает сами пробелы, во-вторых, если между двумя числами только один пробел - не находит второе число


Ответ

Используйте следующее выражение в методе re.findall
r'(?См. демо регулярного выражения
Подробности
(?Код на Python:
import re texts = ['181523539532037 52844 072 301', 'BIC 55555 77777 9999999 554664', '123456'] for text in texts: print('Ищем в {}'.format(text)) print(re.findall(r'(?Вывод:
Ищем в 181523539532037 52844 072 301 ['52844'] Ищем в BIC 55555 77777 9999999 554664 ['55555', '77777', '9999999', '554664'] Ищем в 123456 ['123456']

Функция без пролога и эпилога

Каким образом задать функцию без пролога и эпилога так, чтобы создавался только код тела?
Например, чтобы функция
void func() { __asm__ volatile__ ("nop"); }
компилировалась в код
0: 90 nop
вместо кода
0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 90 nop 4: 5d pop %ebp 5: c3 ret
Есть ли стандартные средства C (visual c, gcc) ?


Ответ

В стандарте C нет такой возможности. Она может предоставляться конкретными компиляторами. Например, для Visual C++ на платформе x86 это будет выглядеть так:
__declspec( naked ) void func( void ) { __asm { nop } }
Для ARM gcc:
void func() __attribute__ ((naked));
void func(void) { __asm__ __volatile__("nop"); }

В чем разница между InnoDB и MyISAM?

В чем разница между движками MySQL - InnoDB и MyISAM? Каковы их слабые и сильные стороны?


Ответ

MyISAM поддерживает сжатие таблиц в отличии от InnoDB. MyISAM имеет встроенные полнотекстный поиск в отличии от InnoDB. InnoDB поддерживает транзакции в отличии от MyISAM. InnoDB поддерживает блокировки уровня строки (MyISAM - только уровня таблицы). InnoDB поддерживает ограничения внешних ключей (MyISAM - нет). InnoDB более надежна при больших объемах данных. InnoDB в теории немного быстрее.

Что такое snapshot в Git?

В книге по Git написано: "Git хранит данные не как последовательность изменений или дельт, а как последовательность снимков состояния (snapshot)." Т.е., как я понимаю, snapshot - это состояние каких-то файлов или папок определенного момента времени. Я пытался найти в .git эти состояния. Так и не нашел. Ну ладно, не важно как в Git'е это реализуется. Но я не могу понять, что мне дает знание того, в чем различие между snapshot и "не как последовательность изменений или дельт". И вообще что мне дает знание того, что такое snapshot.


Ответ

Вы правильно понимаете смысл. Как пользователю эта информация вам никак не поможет, это всего лишь деталь реализации. Если же вы хотите понять, как именно всё внутри устроено, почему некоторые команды требуют больше времени, а некоторые меньше, и как наиболее эффективно работать с git'ом, возможно, эти знания вам пригодятся.

Полнота по Тьюрингу

Как известно, большинство широко используемых языков программирования (особенно императивных) полны по Тьюрингу. А некоторые — даже относительно времени компиляции, как, скажем, С++ с их шаблонами.
А каким образом доказывается/опровергается полнота по Тьюрингу? Само по себе это понятие выглядит трудно формализуемым.


Ответ

Формально это надо доказывать это с точки зрения теории рекурсивных функций — язык полон по Тьюрингу тогда и только тогда, когда он позволяет записать каждую вычислимую функцию. На практике для этого обычно достаточно ловко проапеллировать к [тезису Черча].(http://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis) См. также «How to Prove a Programming Language is Turing Complete?».

Как ВКонтакте, Twitter и другие сервисы генерируют страницы?

У почти у всех социальных гигантов переход на другую страницу происходит без перезагрузки. Для этого они делают запрос, в ответ на который приходит шаблон страницы и данные. Однако когда только пользователь открывает страницу они возвращают уже собранную страницу из шаблона, при этом возвращая так же ее шаблон и данные. Неужели они дублируют код страницы отдаваемой сервером и шаблоны которые отдаются javascript'у? Или есть какой то шаблонизатор способный генерировать шаблоны как для javascript'а так и для серверной части? Если кто знает такие библиотеки для python поделитесь.


Ответ

Вопрос это довольно таки обширный.
Конечно, дублировать код страницы неэффективно с точки зрения затрат на поддержку проекта. В общем случае, всегда стараются избежать любого дублирования кода и контента.
В простейшем случае обновлять всю страницу нет необходимости вообще. У сервера запрашивается лишь "сырая" информация в виде JSON / XML и на текущей странице заменяются соответствующие значения атрибутов или содержимого тегов.
В случае, когда нужно заменять большую часть контента (переход на другую страницу без перезагрузки, например), стараются повторно использовать шаблоны. Шаблоны либо запрашиваются однократно при первом использовании, либо уже внедрены в JavaScript и загружены вместе со страницей.
Могу предложить вам посмотреть на шаблонизатор mustache. Он имеет реализации для большинства используемых языков, включая Python, JavaScript и CoffeeScript. Для более глубокого изучения темы предлагаю для начала вот это – Интерактивные сайты. В частности, вот это – Повторное использование шаблонов

Какой формат быстрее всего распарсится?

Есть кучка данных. Нужно их обработать, переработать и сохранить. Время на переработку - не особо лимитируется. Потом в какой-то момент их нужно максимально быстро считать и отдать. В каком формате их хранить? Т.е. скорость создания файла не важна, а скорость считывания нужна на максимально быстром уровне Размер тоже не важен UPD1 Пока склоняюсь к MessagePack и csv. Итого: CSV


Ответ

О боже, век XML и JSON. Все забыли о бинарных форматах? Быстрее всего - бинарный с полями фиксированной длинны. Вариация на тему DBF, к примеру. Из тех нужно парcить - простой это CSV, к примеру.

Java: объясните поведение компилятора

Здравствуйте! Столкнулся со странным поведением компилятора, объясните пожалуйста, почему происходит вывод разных строк. class EntityModel{ public String name; public EntityModel(){ this.name = "EntityModel"; } public String getName(){ return this.name; } } class Model1 extends EntityModel{ public String name; public Model1(){ this.name = "Model1"; }
@Override public String getName(){ return this.name; } } Вызов: EntityModel m = (EntityModel)new Model1(); System.out.println(m.name); System.out.println(m.getName()); Вывод: EntityModel Model1 Код на ideone.com Почему обращение к полю на прямую и через геттер дают разные результаты?


Ответ

Хе :) Если коротко, то в Java методы виртуальные, а поля — нет. То есть, привязка метода к имени метода производится на этапе выполнения в соответствии с настоящим, динамическим типом объекта, а вот привязка поля — статическая, производится на этапе компиляции. Так сделано потому, что выставлять наружу открытое поле всё равно очень плохая практика, поэтому доступ к полям можно ускорить за счёт точного определения поля во время компиляции. А вот вызывая публичный метод, программист не ожидает вызова не самого «свежего» метода, так что здесь логичнее виртуальный вызов. (Впрочем, архитекторы C# считают не так, но это уже вопрос дизайна языков.) Это всё ещё один аргумент к тому, чтобы делать все поля private, и получать доступ к ним лишь через getter.

Зачем использовать Spring?

Я имею в виду основную функциональность. Я, в общем-то, понял концепцию IoC и DI. Но какие это действительно дает преимущества? Только ли возможность с легкостью сменить одну реализацию класса на другую и не писать везде new? Нигде не нашел прямо прозрачного примера достоинств Spring-а, везде с первого абзаца про общий принцип IoC.


Ответ

Основное преимущество Spring'а - возможность разработки приложения как набора слабосвязанных (loose-coupled) компонентов. Чем меньше компоненты приложения знают друг о друге, тем проще разрабатывать новый и поддерживать существующий функционал приложения. Классический пример - управление транзакциями. Spring позволяет вам управлять транзакциями совершенно независимо от основной логики взаимодействия с БД. Изменение этой логики не порушит транзакционность, равно как изменение логики управления транзакциями не сломает логику программы*. Spring поощряет модульность. Компоненты можно добавлять и удалять (почти) независимо друг от друга. В принципе, приложение можно разработать таким образом, что оно даже не будет знать, что управляется Spring'ом*. Также Spring заметно упрощает модульное тестирование (unit-testing): в компонент, разработанный для работы в IoC контейнере очень легко инжектировать фейковые зависимости и проверить работу только этого компонента. Ну, и в качестве приятного дополнения, Spring сильно облегчает инициализацию и настройку компонентов приложения, позволяя гибко настраивать приложение без существенных изменений Java-кода*.
Ещё раз, кратко:
Поощрение слабой связанности компонентов, и, как следствие... ... упрощение инициализации и настройки компонентов, ... упрощение модульного тестирования, ... упрощение разработки и поддержки приложения в целом.
* Читая эти предложения, делайте скидку на уровень профессионализма программистов, использующих фреймворк. Всегда можно что-нибудь сломать или неоптимально организовать, но в умелых руках Spring весьма эффективен.

export/extern&шаблоны

Интересно, почему export шаблонов deprecated? Знаю только то, что никто не реализовал ее в своих компиляторах кроме компании Edison Design Group, но потом и они признали что это полная "лажа". В чем были сложности?
В новом стандарте, вместо export tempate ввели extern template. Зачем? Некрофилия?


Ответ

Проблема следующая. Шаблоны C++ — функциональность, гораздо более близкая к макросам, чем к функциям/классам. Это чистая конструкция времени компиляции. Невозможно «скомпилировать» шаблон так, чтобы потом можно было просто подлинковать его к программе (в отличие от функций и классов.) Поэтому хранить в объектном файле всё равно придётся текст, никакого выигрыша это не даст.
Почему невозможно заранее скомпилировать шаблон в объектный код? Посмотрите на вот такой простой код:
template void f(T1 t1) { T2 t2 = t1; }
Это копирующая инициализация. В зависимости от типов T1 и T2, а также от видимости других типов в точке использования она может компилироваться в вызов наилучшего из доступных конвертирующего конструктора (и преобразование типа T2 к типу аргумента этого конструктора, если они не совпадают), оператора конверсии, стандартные конверсии, числовые конверсии, включая потерю точности и смену представления между плавающей точкой и целыми числами.
Как вы думаете, можно ли закодировать всё это в объектном коде (то есть, по существу на ассемблере), не зная на момент компиляции типы T1 и T2?

Вот есть целая статья от EDG, с анализом, почему экспорт шаблонов не взлетит и не стоит свеч: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf. И ещё одна: http://blogs.msmvps.com/vandooren/2008/09/24/c-keyword-of-the-day-export/
Более подробно, проблемы следующие (перевёл из статьи EDG):
У EDG на одну эту фичу ушло 1,5 лет на дизайн и 3 года на имплементацию (сравнение: на всю Джаву — только два года). При этом EDG — не «какая-то» компания, у них хорошие разработчики, с многолетним опытом разработки компиляторов C++. Типичная структура компилятора C++ не подходит для имплементации этой фичи. Пришлось переделывать дизайн компилятора, и скорее всего это же придётся сделать всем другим разработчикам, если экспорт станет обязательной частью стандарта. Многие ошибки, которые без экспорта шаблонов было не обязательно детектировать (например, нарушение ODR-rule, которое по стандарту всего лишь UB), с экспортом фактически становится обязательно отлавливать. Форматы промежуточных файлов придётся полностью менять. Эта фича не приносит настолько уж большой пользы:
Считается, что с экспортом шаблонов более не нужно будет поставлять исходный код библиотек. Это не так. Поскольку шаблоны работают на уровне, близком к синтаксическому, то вместе с библиотеками придётся поставлять либо текст шаблонов, либо его прямой эквивалент (например, синтаксическое дерево), поскольку во время инстанциации шаблонов нужна вся эта информация. Считается, что с экспортом шаблонов ускорится компиляция и уменьшится количество зависимостей. Это не так, потому что (вследствие синтаксической природы шаблонов) экспортированный шаблон невозможно заранее скомпилировать. Компиляцию шаблона (по меньшей мере от уровня синтаксического дерева) придётся всё равно повторять, на этот раз на этапе компоновки. Таким образом, компилятору придётся выполнить по меньшей мере ту же работу, что и без экспорта. Единственный реально сработавший плюс экспорта шаблонов — то, что макросы не покидают границы единицы трансляции. (В случае без экспорта, макросы, определённые в файле с шаблоном, «видны» всем, кто использует шаблон.) Этого положительного эффекта, однако, можно добиться при помощи более строгой организации кода; также существуют другие, более лёгкие и эффективные методы решения этой проблемы на уровне стандарта языка.

javascript, замыкания, проблемы синтаксиса

Есть код на JavaScript:
"use strict";
var site = (function () { var loader_html = ''; var loader_image_width = 100; var loader_image_height = 100;
return { window_subroutines : { get_scrollTop : function () { return (document.documentElement && document.documentElement.scrollTop) || (document.body && document.body.scrollTop); }, get_scrollLeft : function () { return (document.documentElement && document.documentElement.scrollLeft) || (document.body && document.body.scrollLeft); }, get_clientWidth : function () { return (document.documentElement && document.documentElement.clientWidth) || (document.body && document.body.clientWidth); }, get_clientHeight : function () { return (document.documentElement && document.documentElement.clientHeight) || (document.body && document.body.clientHeight); } },
loader : { show : function () { var loader_elem = document.getElementById ("loader_container"); var left_coord = Math.round(site.window_subroutines.get_scrollLeft() + ( site.window_subroutines.get_clientWidth() / 2 ) - ( loader_image_width / 2 )) + "px"; var top_coord = Math.round(site.window_subroutines.get_scrollTop() + ( site.window_subroutines.get_clientHeight() / 2 ) - ( loader_image_height / 2 )) + "px";
loader_elem.innerHTML = loader_html; loader_elem.style.top = top_coord; loader_elem.style.left = left_coord;
loader_elem.style.display = "block"; },
hide : function () { setTimeout("document.getElementById('loader_container').style.display = 'none';", 750); } } };
})();
Проблема в том, что при попытке его выполнить браузер выводит ошибку:
SyntaxError: function statement requires a name get_scrollTop : function () { return (document.documentElement && document.docum...
Посмотреть живьём это можно на jsfiddle


Ответ

Надо изменить
return {
на
return {
JavaScript добавляет в конец строка автоматическим образом, так что код распарсится так:
return; { // блок кода window_subroutines: // метка { // блок кода get_scrollTop : // метка function () { /* ... */ } // SyntaxError: декларация функции без имени
(Смотрите в спецификации о инструкциях с метками и автоматической подстановке точки с запятой)

FreeBSD gcc install

Здравствуйте. Стараюсь поставить на FreeBSD 7 x64 gcc посвежее родного 4.2.1. Из портов не ставится. Жалуется на отсутсвие GMP и MPFR (или их кривой путь). По этому ответу поставил нужные библиотеки и с их помощью конфигурил make, который потомвыдавал:
Error expanding embedded variable. Error code 2
Пробовал так же по вышеуказанному ответу собирать gmake'ом, но процесс съедает всю оперативку, и завершается:
virtual memory exhausted: Cannot allocate memory gmake[2]: *** [insn-recog.o] Error 1 gmake[2]: Leaving directory `/root/tmp/gcc-4.9.1/host-x86_64-unknown-freebsd7.2/gcc' gmake[1]: *** [all-gcc] Error 2 gmake[1]: Leaving directory `/root/tmp/gcc-4.9.1' gmake: *** [all] Error 2
Прошу помочь разобраться с этим вопросом.


Ответ

Как насчет дополнительного свапа? Создайте файл нужного размера при помощи dd
dd if=/dev/zero of=/usr/swap0 bs=1m count=64
Затем его нужно разметить как swap
mkswap /usr/swap0
И задействовать
swapon /usr/swap0

Как узнать, есть ли обработчик на теге?

Есть тег. При клике он открывает одну шторку, но я не можу найти обработчик клика на нем в js.
Есть ли какой то способ найти этот оброботчик через инструменты разроботчика?


Ответ

Если речь идет именно об инструментах разработчика, то в Хроме делаем так:
Кликаем правой кнопкой мыши по нужному элементу => Inspect element (или же F12, а затем находим и выделяем нужный элемент в дереве). Далее в правой нижней колонке есть вкладка Event Listeners, там можно найти все обработчики. Соответственно для клика ищем событие click. Если необходимо найти только обработчики событий текущего элемента, снимаем галочку Ancestors, если же возможно, что клик идет по какому-то родителю (что довольно часто бывает), то галку оставляем.

Как сравнить производительность разных виртуальных машин?

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


Ответ

1. Наиболее быстрыми являются виртуальные машины контейнерного типа - все контейнеры используют общее ядро и общие модули уровня ядра, но служебные структуры каждого процесса инициализированы особым образом, что создает иллюзию совершенно разных серверов.
Примеры контейнеров - OpenVZ, Docker. Работают только на линуксе, потому что над другими ОС невозможно надругаться настолько же сильно.
2. Следом за контейнерами в порядке уменьшения производительности идет паравиртуализация. Паравиртуализация - это запуск гостевой ОС полностью на уровне пользователя, для этого для нужной ОС готовят специальные драйвера, которые подменяют все те модули ядра, которым ранее требовался доступ к привилегиям уровня ядра (ring 0 на архитектуре x86/64).
Пример паравиртуальных машин - XEN, User mode linux.
Ограничение - гостевая ОС для работы в паравиртуальном режиме должна быть совместима с используемым гипервизором. Зачастую это ограничение можно читать как "гостевая ОС должна быть линуксом", хотя есть и некоторые исключения.
3. Следующие по тяжести реализации - гипервизоры, использующие аппаратную виртуализацию. Это опять XEN, KVM, VirtualBox, WMWare, Hyper-V и QEMU (в режиме KQEMU)...
Здесь уже нет никаких ограничений на гостевую ОС, кроме наличия под нее драйверов для виртуальных устройств. Но многие реализации эмулируют в качестве "виртуальных" реально существующие устройства, что упрощает проблему с драйверами.
Но тут надо понимать, что несмотря на возможность полной виртуализации на каждой из этих ВМ, все они могут использовать частичную паравиртуализацию для ускорения работы. Поэтому если поставить на ВМ специальный набор "гостевых" драйверов - ее работа ускорится и могут появиться новые возможности. Поэтому при выборе ВМ надо учитывать предполагаемую гостевую ОС и смотреть, какие гостевые драйвера для нее есть.
Обычно считается, что XEN, KVM и VirtualBox быстрее работают когда гостевая ОС - linux, а WMWare и Hyper-V - когда гостевая ОС - Windows.
4. Последний класс, самый медленный - эмуляторы. Снимают ограничение по архитектуре процессора (можно эмулировать ARM на x64 или наоборот) - но работают еще медленнее прошлых классов. Пример - QEMU, BOCHS.
У эмуляторов тоже есть приемы для ускорения выполнения. Но сравнение эмуляторов выходит уже за рамки этого вопроса.

Условие If в лямбда выражении

Есть конструкция вида List> которая используется для формирования строки. Строку формирую так
var val = String.Join(",", insert_res.Where(d => d.Item3 == 0) .Select(d => "'" + d.Item2 + "'"));

Но в зависимости от значения второго строкового параметра мне надо возвращать не в кавычках "'" + d.Item2 + "'", а например в круглых скобках, возможно поместить туда проверку?


Ответ

Есть несколько вариянтов.
Можно использовать тернарный оператор:
var val = String.Join(",", insert_res .Where(d => d.Item3 == 0) .Select(d => condition ? "'" + d.Item2 + "'" : "(" + d.Item2 + ")"));
Тоже можно использовать ламбда блок вместо ламбда выражения:
var val = String.Join(",", insert_res .Where(d => d.Item3 == 0) .Select(d => { if (condition) { return "'" + d.Item2 + "'"; } return "(" + d.Item2 + ")"; }));

Анализ сборок дотнета

Мне необходимо при загрузке дотнет сборки (в виде файла, или набора байтов) на мой сервис получить публичный ключ, которым она подписана, каким образом мне это можно сделать?
Что я пробовал:
Загрузить через Assembly.Load её я не могу, так как у неё могут быть зависимые сборки которые тоже должны быть загружены (а их у меня нет). Создать временный аппдомен, загрузить в него сборку через Assembly.ReflectionOnlyLoad (через маршалинг .DoCallback), а затем выгрузить аппдомен после извлечения публичного ключа. Тут я сталкиваюсь с тем, что даже если я выгружаю аппдомен - у меня периодически падает загрузка пересобранной сборки с той же версией (например для другого фреймворка).


Ответ

Вы можете использовать для этого библиотеку Mono.Cecil которая так же доступна через NuGet.
var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly("fileName"); var publicKey = assembly.Name.PublicKey;

Почему PhpStorm 10.0.1 зачеркивает функции с префиксом mysql_?

PhpStorm не распознает код mysql. Если просто сохраняю проект в notepad то все работает, а когда тот же проект копирую (пишу) в PhpStorm, он зачеркивает команды подключения к mysql. На скрине видно:

PhpStorm настроен с openserver. Может в этом проблема? Что-то еще нужно добавить? Хотя если прямо подключиться к БД из PhpStorm, то все работает нормально.


Ответ

Выдержка из документации
Внимание Данное расширение устарело, начиная с версии PHP 5.5.0, и будет удалено в будущем. Используйте вместо него MySQLi или PDO_MySQL
Прислушайтесь к процитированному совету.
Относительно вашего вопроса: таким образом PhpStorm сигнализирует о том, что вы пытаетесь использовать устаревшие функции, которые будут в будущем удалены.
Эти предупреждения никак не влияют на функциональность вашего приложения. Если не работает подключение к базе данных, вам следует проверить используемую версию PHP.

Что означает “There is 1 zombie process” и что с ним делать?

Залогинился на удаленную машину. Вижу следующую строку в приветственном сообщении.
There is 1 zombie process.
Насколько я понял, это означает, что какой-то процесс завершил работу, но не закрылся и не освободил ресурсы. Хотелось бы лучше понять проблему:
Как можно его обнаружить? Сейчас я угадал, но нужен стабильный метод. Как можно узнать причины его появления? Есть какие-нибудь логи? Может, по имеющемуся процессу можно что-либо понять?
Если это важно, ubuntu 14.04, sudo есть.
Дополнение: меня не устраивает метод «просто подождать», т.к. есть сервис, который должен работать всегда — и подвис он или кто-то из его детей. Он подстрахован monit'ом, но тот не распознал зомбификацию и не перезагрузил.


Ответ

Зомби в операционных системах UNIX называют завершившиеся процессы, код завершения которых не забрал родительский процесс. Зомби не потребляют никаких ресурсов, память и файловые дескрипторы таких процессов уже освобождены. Остается только запись в таблице процессов, которая занимает несколько десятков байт памяти. Так что единичный зомби процесс на систему никак не влияет. НО он явный индикатор того, что у какого то процесса в системе что то пошло не так.
Поиск зомби:
ps -axho state,pid,ppid | grep Z | sed 's/./ps/' | sh
Данная команда покажет все зомби процессы и их родителей (тестировалась под linux, под другими *nix возможны другие ключи у команды ps).
Убить зомби можно только перезапуском родительского процесса. kill -9 самого процесса-зомби и чеснок обычно не помогают. Если появление зомби разовое явление, то возможно проще на факт его появления забить.
Что бы понять почему именно появился зомби надо смотреть исходники породившего его процесса и возможно самого зомби. Часто это одна и та же программа. Любой процесс, выполняющий fork, т.е. запускающий дочерние процессы должен уметь забирать код их завершения, делается это вызовом wait и/или waitpid. Для начала надо просмотреть исходники на наличие функций группы wait, а так же наличие функции-обработчика сигнала SIGCHLD (обработчик устанавливается вызовом signal и функций для работы с сигналами потоков). Если родитель не использует функции группы wait, то возможно при его нормальной работе завершение дочерних процессов разработчик вообще не ожидал. Если это так - то причина образования зомби - незапланированное завершение процесса потомка в следствие какой либо ошибки. Дать рекомендаций как это искать и лечить невозможно. Можно только посоветовать добавить в родительский поток обработку CHLD, забор кода завершения с помощью wait и логирование факта завершения потомка. И дальше запуск потомка под отладчик и т.п. ...
Вариант 2: родительский процесс использует wait, но зомби все равно появляются. Копать в сторону того, какая разновидность wait используется, если waitpid, которая проверяет завершение конкретных потомков, то смотреть откуда она берет проверяемые pid, возможно в процессе работы какие то pid потомков теряются и программа про них забывает. Может программа в какой то момент запрещает обработку сигналов и забывает восстановить обработку, после прохождения критического участка. Опять же - вариантов очень много, но сосредоточены они вокруг обработчика SIGCHLD и функций wait
Вариант 3: родительский процесс умеет обрабатывать и готов правильно обработать завершение своих потомков. Но зацикливается в другом месте программы или засыпает на системном вызове, например чтения с сетевого диска, который стал недоступен и при этом прерывание по SIGCHLD запрещено. В этом случае надо разбираться с причинами его зависания. Кстати, отсутствие доступа к каким либо ресурсам, типа сетевых дисков (или при выходе из строя физического диска) - довольно частая причина массового появления зомби.
Каких либо специальных логов в системе, где можно было бы увидеть хоть какую то информацию по появляющимся зомби не существует. Следы можно найти только в логах той программы, которая их порождает, при их наличии.

Как перенести проект C# из Visual Studio в среду gnu/linux?

Имеется виндовый проект в visual studio, надо перенести его на дистрибутив ubuntu операционной системы gnu/linux.
Как я понимаю, надо первым делом избавится от windows forms и сделать консольный интерфейс. Это сделаю.
Проблема в том что в проекте используется сторонняя библитотека dll (для подключения и работы с внешней БД mysql) Её можно каким-либо образом перенести или следует искать алтернативу под gnu/linux?


Ответ

Как я понимаю, надо первым делом избавится от windows forms
Mono ж вроде имеет свою реализацию Winforms, совместимую по крайней мере процентов на 99. Говорят так. Что же до WYSIWYG, то в штатной IDE нету его для Winforms, только для GTK#, но можно скачать и поставить MWF Designer.
Проблема в том что в проекте используется сторонняя библитотека dll
И опять же, как и с Winforms: почему вы уверены, что она не пойдет на Mono?Библиотека для работы с БД теоретически могла бы хоть на утюге или микроволновке работать, если ОЗУ и ПЗУ хватит. Ничего платформозависимого там не должно быть. (Исключение - ADO.NET и иже с ним, но это не совсем библиотека под .NET, оно завязано на нативном виндовом ADO)Попробуйте написать MySQLьный хелловорлд на Mono - судя по всему, в вашем случае следует начать с этого.

python3, удаление “подсписка” из списка

Нужно удалить из списка в вхождения, да не просто по элементам, а прям множество. Т.е. если есть список: [0, 1, 2, 3, 1, 5, 3, 7], и например, кортеж, который удаляемых элементов (1, 5, 3), нужно, чтобы в итоге получился список [0, 1, 2, 3, 7]. Как можно легче всего такое реализовать?


Ответ

Я бы попробовал что-то вроде такого: 1) изменение списка на месте (чуть сложнее)
def is_equal(lst, pattern): if len(lst) != len(pattern): return False for a, b in zip(lst, pattern): if a != b: return False return True
def clear_list(lst, pattern): index = [] l = len(pattern) rng = iter(xrange(len(lst))) while True: try: i = next(rng) if is_equal(lst[i:i+l], pattern): for j in range(i, i + l): index.append(j) if j != i + l - 1: next(rng)
except StopIteration: break index.reverse() for i in index: del lst[i]
l = [1, 2, 1, 2, 1, 1, 2, 1, 3, 4, 1] p = (1, 2, 1) clear_list(l, p) print l # --> [2, 1, 3, 4, 1]
Оно даже работает.

2) для генерации нового списка (все проще):
def clear2(lst, pattern): res = [] l = len(pattern) r = iter(xrange(len(lst))) while True: try: i = next(r) if is_equal(lst[i:i+l], pattern): for j in range(i, i + l - 1): next(r) else: res.append(lst[i]) except StopIteration: break return res
l = [1, 2, 1, 2, 1, 1, 2, 1, 3, 4, 1, 2] p = (1, 2, 1) print l print clear2(l, p) # -> [2, 1, 3, 4, 1, 2]

Потестил на 5 примерах, оба варианта рабочии.