Страницы

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

воскресенье, 15 декабря 2019 г.

Запрещение кастинга виртуального базового класса

#cpp


Почему запрещён кастинг в следующем коде?

class Base
{
};

class Derived : virtual public Base
{
};

int main()
{
    Base *p = new Derived;
    static_cast(p);
    return 0;
}

    


Ответы

Ответ 1



Компилятор не может скастовать Base* к Derived*, потому что он не делает полный анализ кода, а значит не знает как именно расположены типы друг относительно друга. Если существуют только типы Base и Derived, то при касте Base* в Derived* надо добавить смещение в 0 байт, т.к. адреса Derived и Base совпадают. Однако компилятор допускает, что может существовать другие типы, например struct Derived2 : virtual Base { char x[1024]; }; struct MostDerived : virtual Derived2, Derived {}; И Base* p может указывать на объект этого типа. Тогда MostDerived выглядит в памяти так: смещение | что находится 0 | MostDerived 0 | Base 0 | Derived2 0 | char Derived2::x[1024] 1024 | Derived Виртуальный базовый класс Base, находится в Derived2, самом первом базовом классе MostDerived. Т.к. Base - это пустой базовый класс, он не занимает никакого места в памяти. После Derived2 будет располагаться Derived, уже без Base. По этому в этом случае при касте Base* в Derived* надо добавить смещение в 1024 байт. Т.к. компилятор не знает какое именно смещение надо использовать, он не может сделать такой static_cast. По этому для виртуальных базовых типов поддерживается только dynamic_cast, и то, только для типов в которых есть виртуальные функции.

Тип timestamp отображается как DATETIME

#mysql #sql


Установил в таблице тестовой тип поля timestamp, и при добавлении туда значения в
виде 1421312123 оно отображается как 0000-00-00 00:00:00

Почему так происходит?

Перепроверяю, тип действительно timestamp.
    


Ответы

Ответ 1



тип timestamp хранит дату и время (отметку времени): The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. вы же пытаетесь вставить в столбец число (в математическом смысле этого слова). это число весьма похоже на количество секунд, прошедших с 1970-01-01 00:00:01 по 2015-01-15 11:55:23 (в московском часовом поясе), т.е., на unix-время (unix timestamp). если так, то нужно преобразовать это число в дату и время с помощью функции from_unixtime. примерно так: insert into t values (from_unixtime(1421312123)); тогда в столбец с типом timestamp попадёт корректное значение, и эта отметка времени будет корректно отображаться: select * from t; +---------------------+ | d | +---------------------+ | 2015-01-15 11:55:23 | +---------------------+

Rails + Devise + Angular2: аутентификация

#ruby_on_rails #безопасность #devise #csrf #angular2


У меня просто огромное количество вопросов... Но перед этим нужно описать, что собственно
происходит.

Преамбула

Я пытаюсь научить Angular2 авторизироваться в Rails 5 beta 3 приложении. При этом
Rails работает в режиме API. Как я понимаю, для того, чтобы Devise работал в режиме
API, нужен gem devise_token_auth. Гем я установил и настроил, но вот после этого начались
проблемы:

Unpermitted parameters: user, session

Первое, что я попробовал сделать после настройки, послать простой POST запрос и посмотреть,
что произойдёт. А произошло следующее: 

Processing by DeviseTokenAuth::SessionsController#create as *json*
  Parameters: {"user"=>{"username"=>"demo", "password"=>"[FILTERED]"}, "session"=>{"user"=>{"username"=>"demo",
"password"=>"[FILTERED]"}}}
Unpermitted parameters: user, session
  Rendered devise_token_auth/sessions/create.json (0.2ms)
Completed 401 Unauthorized in 18ms (Views: 3.2ms | ActiveRecord: 0.0ms)


И вот с этого момента я немного не понимаю, с каких это пор я должен прописывать
permit для параметров, которые ActionController::ParamsWrapper создаёт динамически
в качестве обёртки? Более того:

devise_parameter_sanitizer.permit(:sign_in) do |user_params|
  user_params.permit(:user, :session)
end


ничего не меняет. Кто-нибудь сталкивался с подобным ранее?

Authentication header

Покопавшись в документации в поисках решения проблемы я нашёл другую:


  The authentication information should be included by the client in the headers
of each request. The headers follow the RFC 6750 Bearer Token format


Т.е. в заголовке запроса должны быть следующие данные:

"access-token": "wwwww",
"token-type":   "Bearer",
"client":       "xxxxx",
"expiry":       "yyyyy",
"uid":          "zzzzz"


В AngularJS они генерировались модулем ng-token-auth, но как мне сгенерировать их
посредством Angular2, у которого данного модуля нет?



Подводя промежуточный итог (потому что чувствую я, после этих проблем я наткнусь
на их ещё большее количество), вот список моих вопросов:


Как исправить unpermitted parameters: user, session в devise_token_auth?
Как сгенерировать access-token?
Как высчитать expiry и есть ли "rails-way" для времени жизни токена?
Что следует писать в client? Раз уж этот идентификатор позволяет пользователю одновременно
авторизироваться с нескольких устройств, то как он должен выглядить? Что туда следует
записать?





Какие данные следует возвращать клиенту после авторизации (помимо 200)?
Какие ещё подводные камни могут меня ждать при попытке авторизироваться через Rails API?




UPD

Вот запрос, который я шлю:

private _user_session_url = 'auth/sign_in';

login (username: string, password: string) : Observable {
    let body = JSON.stringify({ username: username, password: password });
    // TODO: generate header data.
    let headers = new Headers({
        'Content-Type': 'application/json',
        'accept': 'json'
    });
    let options = new RequestOptions({ headers: headers});

    return this.http.post(this._user_session_url, body, options)
        .map((data: any) => data.json())
        .catch(this.handleError)
}


Как видите, session в теле запроса нет. Его создаёт ActionController::ParamsWrapper

В подтверждение привожу Request Payload:

{"username":"demo","password":"123"}    

    


Ответы

Ответ 1



Согласно краткой документации к devise_token_auth (DTA) POST /sign_in принимает только параметры email и password прямо в корне. То есть, параметры должны выглядеть так: { "email": "foo@example.com", "password": "bar" } Никакой вложенности. Не надо дополнительно настраивать санитайзер и придумывать ненужные ключи. А теперь ответ разом на все оставшиеся вопросы: Token-Type, Access-Token, Client и Expiry. В AngularJS они генерировались модулем ng-token-auth Нет, они генерируются сервером, клиент ничем умным не занимается. Хранятся они в БД (в частично искажённом, но проверяемом виде, как пароли), а обмен ими происходит с помощью заголовков. /sign_in возвращает все интересующие заголовки. Все эти значения вы просто будете передавать туда-сюда (и обновлять, ведь по умолчанию после каждого отдельного запроса токен меняется). Кроме, разве что, Expiry, значением которого можно следить, "когда токен отвалится и потребует обновления", что можно использовать для выкидывания на форму входа. Пользоваться DTA без ng-token-auth можно, но прежде чем за это браться, стоит прочесть документацию к используемым методам. Я пользовался этим гемом ранее и не рекомендую его для случаев, где важна настраиваемость принимаемых и отдаваемых этой системой данных, потому что расширяемость гема близка к нулю.

SOLID - обсуждение Open Closed Principle

#php #solid



  Бертран Мейер в основном известен как основоположник термина Принцип открытости/закрытости,
который появился в 1988 году в его книге Object-Oriented Software Construction. Идея
была в том, что однажды разработанная реализация класса в дальнейшем требует только
исправления ошибок, а новые или изменённые функции требуют создания нового класса.
Этот новый класс может переиспользовать код исходного класса через механизм наследования.
Производный подкласс может реализовывать или не реализовывать интерфейс исходного класса.


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

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

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

Из википедии:


  Solid - принципы, когда применяются вместе, предназначены для повышения вероятности
того, что программист создаст систему, которую будет легко поддерживать и расширять
в течение долгого времени[3]. Принципы SOLID - это руководства, которые могут применяться
во время работы над программным обеспечением для удаления запахов кода предписывая
программисту выполнять рефакторинг исходного кода, пока тот не станет разборчиво написанным
и расширяемым. Это часть общей стратегии гибкой и адаптивной разработки


Но данный принцип противоречит концепции (разборчиво написанного кода и расширяемости).
Т.е если у нас уже есть множество созданных объектов 'Человек', и в проекте мы хотим
чтобы они теперь могли общаться, после добавления данного метода в другой класс, мы
должны все наши объекты создать на базе другого класса. 

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


Ответы

Ответ 1



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

Не приходят сообщения на почту

#php #jquery #ajax


Не приходят сообщения на почту. На локалке все работает адекватно. Выгружаю все на
хостинг и сообщения не приходят. В чем может быть причина?

Сама форма:




JS:  

$('#phone-call').submit(function(event) {
    event.preventDefault();
    $.ajax({
        url: 'feedback_lib.php',
        beforeSend: function() {
            $('#load').fadeIn(400);
        },
        type: 'post',
        data: $('#phone-call').serialize(),
        success: function(answer) {
            $('#answer').html(answer);
        }
    }).done(function() {
        $('#load').fadeOut(400),
        $('.subm').html('Спасибо за заявку!');
    });
});


PHP:  

if (preg_match('~[^а-яёА-ЯЁ ]~u', $name)) $result = 1;
else {
if (preg_match('/^\d+$/', $phone)) {
    $subject = "Письмо с Вашего сайта http://" . $_SERVER["HTTP_HOST"] . "/";
    $header = "From <" . $email . ">\r\nContent-type: text/plain; charset=utf-8\r\n";
    mail($subject, $message, $header, $recepient);
    mail($subject, $message1, $header, $copy);
    $result = 5;
} else $result = 4;
}
echo getAnswer($result);

    


Ответы

Ответ 1



Установи sendmail на хостинг, если нету прав напиши админам, чтобы они установили.

Ответ 2



Во первых - посмотри ошибку после вызова mail print_r(error_get_last()) Во вторых - можно использовать эту библиотеку PHPMailer И с ее помощью отправлять письма со своей почты.

Java. Вопросы по многопоточности

#java #многопоточность #java_ee #jvm



К примеру у меня есть какой-то объект типа Object многопоточное чтение которого происходит
гораздо чаще, чем модификация и есть два варианта реализации:

a)  обычная переменная Object obj и ReadWriteLock соответственно на методы чтения
и модификации

б) volatile Object obj, на метод модификации - простой Lock, создание нового объекта
и замены ссылки obj. Метод чтения без синхронизации(не считая записи-чтения volatile
переменной)

Какой из вариантов предпочтительнее и будет работать быстрее и почему?
Если я решил делать вариант 1.б и точно знаю, что мое приложение будет запускаться
на сервере с несколькими процессорами архитектуры x86-64, то мог ли я вообще убрать
volatile и нарушив тем самым JMM, но полагаясь на протоколы когерентности кешей процессоров?
прочитает ли ядро 2-го процессора измененные данные в ядре первого и даст ли это хоть
какой-то прирост производительности? 

    


Ответы

Ответ 1



Интересный вопрос. Попробую ответить, хотя не претендую на правильность. Буду рад замечанием в комментариях. 1) Какой вариант будет быстрее? Сказать трудно, потому что все сильно зависит от usecas'а который вы используете. А именно, от количества писателей и читателей, частоты записи и чтения, потребность в "честной" синхронизации или ее критичности и пр. В общем, нужно замерять и писать тесты. Написал для этого вот такой код : Для варианта с Lock: private Object object = new Object(); private final ReentrantLock lock = new ReentrantLock(); Supplier reader = () -> { while (lock.isLocked()) { } return object; }; Function writer = number -> { lock.lock(); object = number; lock.unlock(); return object; }; Насколько я знаю, isLocked() и unlock() имеют отношение happens-before и надобности в volatile для поля object нет. Варианта с ReentrantReadWriteLock довольно простой: private Object object = new Object(); private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); Supplier reader = () -> { Object result; readWriteLock.readLock().lock(); result = object; readWriteLock.readLock().unlock(); return result; }; Function writer = number -> { readWriteLock.writeLock().lock(); object = number; readWriteLock.writeLock().unlock(); return object; }; Результаты получились следующие, если отношение между читателями и писателями 0.8 то вариант с обычным lock оказывается быстрее в 2.5-4 раза (полный код теста с jmh) 2) Из полученных измерений пришел к выводу, что удаление volatile не сыграет существенной роли. Лучше посмотреть в сторону каких-то альтернативных механизмов синхронизации.

Как в phpstorm подключить папку вне проекта

#php #phpstorm


Хочу подключить папку к проекту и работать в ней но она лежит вне папки проекта,
как это можно сделать?
    


Ответы

Ответ 1



Откройте настройки (ctrl + alt + s), зайдите в раздел Directories и справа добавьте новый content root: После этого в дереве каталогов проекта появится новая папка.

Ответ 2



Заходим с Settings->Directories. Там будет +Add Content Root. Добавляем папку и наслаждаемся.

Как в MySQL выбрать строки, значение столбца которых повторяется не более 2х раз

#mysql #sql


Имеется таблица

id|cat_id|name
 1|     1|test1
 2|     1|test2
 3|     2|test3
 4|     3|test4
 5|     3|test5
 6|     1|test6


Нужно сделать выборку так, чтобы в ней было не более чем 2х товаров из каждой категории.
Как это сделать?

Вот ссылка на БД, для проверки
https://dl.dropboxusercontent.com/u/8025044/table.sql
    


Ответы

Ответ 1



Думаю проще всего это будет сделать с использованием переменных: select * from ( select T.*,@n:=if(@cat=cat_id,@n+1,1) as Num,@cat:=cat_id from test7 T,(select @n:=0,@cat:=0) A order by cat_id ) A where Num<=2 Сортировка во внутреннем подзапросе должна обязательно начинаться с cat_id, далее к ней можно добавлять другие поля, что бы регулировать какие именно из двух записей показывать. Вариант "обычным SQL": select * from test7 where id in(select max(id) from test7 group by cat_id union select min(id) from test7 group by cat_id ) Из ограничений метода: из любой группы всегда выбирается запись с минимальным и максимальным ID.

Полезный смысл функции с аргументом &&rvalue против const&lvalue при копировании значения

#cpp #cpp11


Рассмотрим следующий псевдокод:

класс Параметр {
    double значение_;
public:
    Параметр& задать(const double& зн){ значение_=зн; return *this; }
    Параметр& задать(double && зн){ значение_=зн; return *this; }
};


но вернее будет общий случай:

template
класс Параметр {
    T значение_;
public:
    Параметр& задать(const T& зн){ значение_=зн; return *this; }
    Параметр& задать(T && зн)    { значение_=зн; return *this; }
};



В чём может быть профит от использования здесь rvalue? Я понимаю, что так как в любом
случае идёт копирование в rvalue нет никакого смысла.
Покажите, пожалуйста, на примере близком к этому когда же может получится польза.


На (2) пример бы написал такой(благодарю ixSci)

класс Параметр {
    std::string значение_;
public:
    Параметр& задать(const std::string & зн){ значение_=зн; return *this; }
    Параметр& задать(std::string && зн)     { значение_=std::move(зн); return *this; }
};


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


Ответы

Ответ 1



В первом куске кода ссылки не нужны вообще, так что в обоих примерах их нужно убрать — там лучше обычное копирование, т.к. double. Второй пример — другое дело. Давайте рассмотрим возможные варианты вызова функции задать: задать("тему"). Для такого вызова сначала будет создан временный объект типа std::string, затем, для варианта с const&, будет вызван оператор присваивания, который выделит память, скопирует строку, а потом будет вызван деструктор временного объекта, который удалит временный объект и память, которую он выделял на куче(в случае оптимизации малых строк, никакой памяти не будет, но это оставим за скобками). Во втором варианте никакого копирования не произойдёт, вернее произойдёт копирование указателя, из временного объекта в постоянный.Что гораздо быстрее, чем копирование всей строки(с предварительным выделением памяти), после чего будет так же вызван деструктор временного объекта, который ничего уже не будет делать. Все плюсы перемещающей семантики зависят исключительно от того, как реализован перемещающий конструктор(оператор присваивания). В std::string он реализован так, чтобы он имел преимущества перед копированием. К этому должен стремиться любой класс содержащий ресурсы. В стандартной библиотеке этим преимуществом пользуется все классы, которые могут.

Ответ 2



rvalue-ссылка интресена только для объектов, чей класс предусматривает оптимизорованный продуманный специальный конструктор перемещения. Хорошая STL - хороший пример. На простых типах от неё толку как от обычной ссылки - может сэкономить копирование нескольких маш.слов = sizeof(type)-sizeof(void*). То есть при копировании большого массива double на 32-битной машине даст 2ую экономию. подходит. Благодарю @ixSci. Я перефразировал до краткости по сути вопроса.

Сложность с D3D хуком

#cpp #dll #directx #hook


Здравствуйте! Пытаюсь сделать меню для игрушки, но не могу разобраться в функции,
которая крашит программу после инъекции. Опишу все подробно с комментариями, если я
не прав, пожалуйста поправьте:
Создаю поток в процессе (инжект работает нормально) с таким содержимым:

    DWORD*vtbl = 0;
    //Здесь я записываю начальный адрес модуля 
    DWORD hD3D9 = (DWORD)LoadLibraryA("d3d9.dll");
    //ищу функцию Direct3DCreate или что то другое?
    DWORD table = MemHack->FindPattern(hD3D9, 0x128000, (PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86",
"xx????xx????xx");//
    // со смещением в 2 байта копируем указатель
    memcpy(&vtbl, (void*)(table + 2), 4);


Здесь table = 6ace76d3. Вот кусок памяти:

d3d9.Direct3DCreate9Ex+54AC - E8 71000000           - call        d3d9.Direct3DCreate9Ex+5522
d3d9.Direct3DCreate9Ex+54B1 - 33 C0                 - xor eax,eax
d3d9.Direct3DCreate9Ex+54B3 - C7 06 9C86CD6A        - mov [esi],d3d9.dll+869C { [6ACD9D30] }
d3d9.Direct3DCreate9Ex+54B9 - 89 86 08310000        - mov [esi+00003108],eax
d3d9.Direct3DCreate9Ex+54BF - 89 86 00310000        - mov [esi+00003100],eax


Далее идет вызов функции, который крашит программу:

// vtbl[42] указывает на функцию endScene размером 5 байт?
pEndScene = (oEndScene)Mem->Create_Hook((PBYTE)vtbl[42], (PBYTE)myEndScene, 5);


Приведу код функции, который в общем представлении я не понял:

void * cMemory::Create_Hook(BYTE *src, const BYTE *dst, const int len)
{
    BYTE *jmp;
    DWORD dwback;
    DWORD jumpto, newjump;

    VirtualProtect(src,len,PAGE_EXECUTE_READWRITE,&dwback);
    // вот отсюда я не понял зачем эта проверка вообще нужна
    if(src[0] == 0xE9)
    {
        jmp = (BYTE*)malloc(10);
        jumpto = (*(DWORD*)(src+1))+((DWORD)src)+5;
        newjump = (jumpto-(DWORD)(jmp+5));
        jmp[0] = 0xE9;
        *(DWORD*)(jmp+1) = newjump;
        jmp += 5;
        jmp[0] = 0xE9;
        *(DWORD*)(jmp+1) = (DWORD)(src-jmp);
    }
    else
    {
        jmp = (BYTE*)malloc(5+len);
        memcpy(jmp,src,len);
        jmp += len;
        jmp[0] = 0xE9;
        *(DWORD*)(jmp+1) = (DWORD)(src+len-jmp)-5;
    }
    src[0] = 0xE9;
    *(DWORD*)(src+1) = (DWORD)(dst - src) - 5;

    for(int i = 5; i < len; i++)
        src[i] = 0x90;

    VirtualProtect(src,len,dwback,&dwback);
    // здесь указатель на функцию?
    return (jmp-len);
}

    


Ответы

Ответ 1



Ваши ошибки: Игра написана на directX8, а не 9 версии, Вы пытаетесь хукнуть 9 версию, собственно LoadLibraryA("d3d9.dll"), нужно LoadLibraryA("d3d8.dll") и в таблице виртуальные методы там, на сколько я помню, имеют немного другую последовательность (для проверки того, какую версию dx использует приложения нужно всего лишь открыть отладчик и просмотреть список загруженных модулей или посмотреть инфо в википедии). Вы пытаетесь(скорее всего, это мои догадки) сделать иньекцию кода в процесс generals.exe, но это просто дочернее окно и оно не выполняет функции отрисовки игрового мира\меню и т.д., Вам нужен процесс game.dat. Вечером, когда приду домой, постараюсь переделать Ваш код в рабочее состояние и дополню ответ. Если Вам интересно, можете почитать интересную статью по Вашей теме. UPD: #include #include #include #pragma comment (lib, "d3d8.lib") #pragma comment (lib, "d3dx8.lib") #pragma comment( lib, "LIBCI.lib" ) #include "MessageControll.h" #include "ConsoleControll.h" //"Game.dat"+0056C9A4 // Hook Function HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *params); // Orig Function typedef HRESULT(WINAPI* tPresent)(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); typedef HRESULT(WINAPI *tReset)(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *pp); DWORD origReset = 0, origPresent = 0; tPresent _tPresent = nullptr; tReset _tReset = nullptr; ID3DXFont* pFont = nullptr; void createFont(IDirect3DDevice8* pDevice) { LOGFONT log_font = { 50, //height 0, //width; 0, // lfEscapement; 0, //lfOrientation; FW_BOLD, // lfWeight; FALSE, // lfItalic; FALSE, // lfUnderline; FALSE, // lfStrikeOut; DEFAULT_CHARSET, // lfCharSet; OUT_DEFAULT_PRECIS, //lfOutPrecision; CLIP_DEFAULT_PRECIS, // lfClipPrecision; ANTIALIASED_QUALITY,// lfQuality; DEFAULT_PITCH,// lfPitchAndFamily; "Tahoma"// lfFaceName[LF_FACESIZE]; }; HFONT font = CreateFont(10, 10, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, 0, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); if (D3DXCreateFontIndirect(pDevice, &log_font, &pFont) != D3D_OK) { console("D3DXCreateFontIndirect error!"); } } VOID D3DX_Font(LPDIRECT3DDEVICE8 Device_Interface) { RECT Rect = { 0,0,1000,1000 }; //if (Device_Interface != NULL) //{ // HFONT Logical_Font_Characteristics = CreateFont(16, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 2, 0, "Arial"); // if (Logical_Font_Characteristics != NULL) // { // D3DXCreateFont(Device_Interface, Logical_Font_Characteristics, &pFont); // DeleteObject(Logical_Font_Characteristics); // } //} if (pFont != NULL) { pFont->Begin(); pFont->DrawText("StackOverflow.ru!", -1, &Rect, 0, 0xFFFF0000); pFont->End(); } } //========================================================= //if (bDrawText && m_pFont) //{ // PrintTextB(m_pFont, // 250, 20, //x, y // 255, 255, 255, 255, //color values (and then alpha) // "Testing 1234567890!!!"); //} //My custom PrintText Function: //void drawText(const D3DXVECTOR4& area, const DWORD& color, TCHAR *text, ...) //{ // TCHAR buf[1024]{}; // // RECT FontRect = { // // (long)area.x, // (long)area.y, // (long)area.x + (long)area.z, // (long)area.y + (long)area.w // }; // // va_list vaList; // va_start(vaList, text); // //#ifdef UNICODE // vswprintf_s(buf, text, vaList); //#else // vsprintf_s(buf, text, vaList); //#endif // // va_end(vaList); // // pFont->Begin(); // pFont->DrawText(buf, -1, &FontRect, 0, color); // pFont->End(); //} void* DetourCreate(BYTE *src, const BYTE *dst, const int len) { BYTE *jmp; DWORD dwback, dwold; DWORD jumpto, newjump; VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwback); if (src[0] == 0xE9) { jmp = (PBYTE)malloc(10); VirtualProtect(jmp, 10, PAGE_EXECUTE_READWRITE, &dwold); jumpto = (*(DWORD*)(src + 1)) + ((DWORD)src) + 5; newjump = (jumpto - (DWORD)(jmp + 5)); jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = newjump; jmp += 5; jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = (DWORD)(src - jmp); } else { jmp = (PBYTE)malloc(5 + len); VirtualProtect(jmp, 5 + len, PAGE_EXECUTE_READWRITE, &dwold); memcpy(jmp, src, len); jmp += len; jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5; } src[0] = 0xE9; *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5; for (int i = 5; i < len; i++) { src[i] = 0x90; } VirtualProtect(src, len, dwback, &dwback); return (jmp - len); } void GetDevice9Methods() { D3DDISPLAYMODE ds{}; D3DPRESENT_PARAMETERS pp{}; IDirect3DDevice8* dev{}; HMODULE hD3D8Dll = GetModuleHandle("d3d8.dll"); //console("address \"d3d8.dll\" [%#x]", hD3D8Dll); //Инициализируем свой девайс, чтобы узнать адреса функций ресета и презента в виртуальной таблице методов if (hD3D8Dll) { IDirect3D8* d3d8 = Direct3DCreate8(D3D_SDK_VERSION); //console("address \"IDirect3D8\" [%#x]", d3d8); if (d3d8->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ds) != D3D_OK) { d3d8->Release(); return; } pp.Windowed = 1; pp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; pp.BackBufferFormat = ds.Format; if (d3d8->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetForegroundWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &dev) == D3D_OK) { if (dev) { //Копируем адреса виртуальных методов origReset = *((DWORD*)(*(DWORD*)dev) + 14); origPresent = *((DWORD*)(*(DWORD*)dev) + 15); //console("address \"Reset method\" [%#x]", origReset); //console("address \"Present method\" [%#x]", origPresent); dev->Release(); d3d8->Release(); } } else { d3d8->Release(); return; } } } DWORD WINAPI InitThread(HINSTANCE hinstDLL) { //t_con.create(); GetDevice9Methods(); if (origReset && origPresent) { _tPresent = (tPresent)DetourCreate((PBYTE)origPresent, (PBYTE)HookedPresent, 5); _tReset = (tReset)DetourCreate((PBYTE)origReset, (PBYTE)HookedReset, 5); } while (!GetAsyncKeyState(VK_END)) { Sleep(1); } //t_con.del(); FreeLibraryAndExitThread(hinstDLL, 0); return 1; } HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) { if (!pFont) { createFont(pDevice); } else { D3DX_Font(pDevice); } D3DRECT rec = { 10, 10, 30, 30 }; //pDevice->Clear(1, &rec, D3DCLEAR_TARGET, 0xFFFF0000, 1.0f, 0); return _tPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); } HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *params) { return _tReset(pDevice, params); } BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH://Вызывается первым CreateThread(0, 0, LPTHREAD_START_ROUTINE(InitThread), hinstDLL, 0, 0); return 1; case DLL_PROCESS_DETACH://вызывается после освобождения библиотеки break; case DLL_THREAD_ATTACH://вызывается при создании потока break; case DLL_THREAD_DETACH://вызывается после разрушения потока break; } return TRUE; } Как пофиксить проблемы с нехваткой libci: Скачать саму либу и заинклудить в проект; Заинклудить дополнительные зависимости, как сказано тут. Результат:

Что такое double rounding error (ошибка двойного округления)?

#ieee_754


Слышал, что при работе с числами с плавающей запятой возможна так называемая ошибка
двойного (повторного) округления (double rounding error), особенно когда имеют место
переходы от одинарной точности (float) к двойной (double) и наоборот. Как это понимать?
    


Ответы

Ответ 1



Эта ошибка мало известна в среде обычных профессиональных программистов, потому что возникает она крайне редко, да и то в задачах с особой спецификой. Почти наверняка вы никогда её не встретите. Но знать о ней нужно хотя бы для общего развития и повышения культуры работы с арифметикой с плавающей запятой. В чём суть ошибки? Ошибка двойного округления иногда возникает в тех случаях, когда вместо одного округления выполняется два последующих друг за другом округления. Рассмотрим пример в десятичной системе счисления. У нас есть число 1,34999. Если мы сразу округлим его до одного знака после десятичной запятой, то получим 1,3. Но если сначала округлить до двух знаков, а потом до одного, то получим 1,35, а затем 1,4. Как мы видим, результаты получились разными, причём существенно! Как это связано с моей программой? В вашей программе могут быть, как минимум три (больше я просто не знаю) места, где может быть ошибка двойного округления. Вы используете тип данных double размером 64 бита, но на вашем компьютере нет команд, которые работают с double (или компилятор их не поддерживает), а есть только сопроцессор x87. Таким образом, любая операция с double выглядит так: происходит расширение типа с 64-х до 80-ти битов, затем, собственно, необходимые вычисления, в которых результат округляется до 63-х битов дробной части мантиссы (такова структура 80-битового числа с плавающей запятой), а затем происходит второе округление до 52-х битов дробной части мантиссы в double. Пример программы. Числа для кода я позаимствовал у @Mark Dickinson из англоязычного SO. Вы знаете, что long double размером 80 битов в настоящий момент не поддерживается (например, в VC++ точно), а заменяется на обычный double. Поэтому пример работать не будет, если не указать специальную опцию компилятора, которая заставит его работать через x87. У каждого компилятора своя такая опция (если вообще есть). #include int main (void) { double a = 1e16 + 2.9999, b; long double x = 1e16L, y = 2.9999L; b = (double)(x+y); printf ("a = %16.0lf, b = %16.0lf\n", a, b); return 0; } Программа выдаст два разных целых числа: 10000000000000002 и 10000000000000004, показывая, тем самым, разницу, возникшую в результате двойного округления. Вы используете функции, которые созданы специально для double, но подаёте им на вход числа float. Скажем, есть функция sqrt для double. Если передать ей на вход число float, то произойдёт расширение его до double, затем функция вычислит результат с округлением, а затем выполнится второе округление, если вы присваиваете результат обратно во float. К сожалению, каких-то реальных примеров подобной ошибки мне отыскать не удалось, но чисто теоретически любая подмена float на double и обратно может дать ошибку двойного округления. Это будет хорошо видно на последнем, самом любопытном примере. Данное наблюдение я подсмотрел в статье “Double Rounding Errors in Floating-Point Conversions”, но сделал свой собственный пример. Общий смысл таков, что константа может быть неверно преобразована в бинарный формат на этапе компиляции, если произойдёт двойное округление. Это может произойти когда когда вы забыли суффикс f для чисел типа float или если пользуетесь VC++ любой версии. Для демонстрации за основу будет взято число 1+2-23+2-24-2-54. Оно равно 1.000000178813934270660723768742172978818416595458984375. Это число интересно тем, что в двоичном формате оно равно 1,000000000000000000000010111111111111111111111111111111(2) Полужирным шрифтом я отметил биты 24 и 53-54. Если читатель не знаком с правилами округления чисел в формате IEEE-754, то ему придётся сначала их изучить. Например, здесь. Если мы хотим перевести данное число в формат float, то никаких проблем нет: 24-й бит равен нулю, а значит округление до 23-х бит, необходимых float, произойдёт вниз без вопросов. Получим число 1,00000000000000000000001, что в формате IEEE-754 будет иметь вид 0x3f800001. Если же мы сначала приводим число к типу double, то округление до 52-х бит сначала произойдёт вверх, и мы получим 1,0000000000000000000000110000000000000000000000000000, а затем, из-за того, что 23-й и 24-й биты теперь равны 1, в результате второго округления до float получим 1,00000000000000000000010 (снова округление произошло вверх), что в шестнадцатеричной записи будет иметь вид 0x3f800002. Как видно, мы получили два разных числа. Рассмотрим демонстрационный код (не плюйтесь, что в коде есть грязные трюки, здесь я хочу просто и без хитростей показать биты числа): #include typedef unsigned int u32; typedef unsigned long long u64; int main (void) { float a, b; double c; a = 1.000000178813934270660723768742172978818416595458984375f; b = 1.000000178813934270660723768742172978818416595458984375; c = 1.000000178813934270660723768742172978818416595458984375; printf ("a = %08x, b = %08x, c = %016llx\n", *(u32*)&a, *(u32*)&b, *(u64*)&c); return 0; } Здесь переменная a инициализируется правильно, мы используем суффикс f, инициализация переменной b происходит так, будто программист забыл про суффикс f (к счастью, многие компиляторы ему об этом напомнят), поэтому здесь произойдёт двойное округление (сначала константа превратиться в double, а затем будет присвоена к float), а переменная c здесь просто так, для демонстрации промежуточного округления в double. Функция printf выводит шестнадцатеричный код всех трёх переменных. Компилятор Tiny C выдаёт верный ответ: a = 3f800001, b = 3f800002, c = 3ff0000030000000 Такой же точно ответ выдали Intel C 15 и Clang. Компилятор VC 2015 выдал a = 3f800002, b = 3f800002, c = 3ff0000030000000 Это значит, что он ИГНОРИРУЕТ суффикс f, если он установлен, и в любом случае приводит результат сначала к double, а потом к float, если нужно. По-хорошему, разработчики компилятора заработали этим сильный удар линейкой по пальцам. Копилятор GCC из MinGW выдал также неверный ответ a = 3f800001, b = 3f800001, c = 3ff0000030000000 То есть с точки зрения исходного желания программиста ответ верный (и здесь он молодец, что угадал это желание), но с точки зрения Стандарта - нет. Что же теперь делать? Повышайте культуру работы с числами с плавающей запятой, никогда не делайте необоснованного расширения типа данных с тем, чтобы потом вернуться обратно. Да, зачастую это оправдано, но оправдание должно быть не чисто интуитивным, а строго доказанным. Будьте осторожны, и да минуют вас ошибки двойного округления.

Как правильно импортировать модуль JavaScript

#javascript #webpack #сборка


В проекте имеется директория frontend следующей структуры:

├── common
    ├── static
           ├── css
           ├── js
                └── common.js
├── node_modules
├── package.json
├── app
    ├── static
           ├── css
           ├── js
                └── script1.js
                └── script2.js
└── webpack.config.js


Классы и некоторые методы, которые я определил в common.js, мне нужны в script1.js
и script2.js. Я их импортировал как

 import './common/static/js/common.js'
 import { Class1, Class2 } from './common/static/js/common.js'


Но при сборке webpack --display-error-details сообщает об отсутвующем модуле

ERROR in ./app/static/app/js/settings.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./common/static/js/common.js
in      .../frontend/app/static/table/js resolve file

 .../frontend/app/static/table/js/common/static/js/common.js doesn't exist


То есть webpack ищет файл в том же каталоге, где располгается вызывающий скрипт,
а не каталог frontend.

Я понимаю, что могу задать инструкцию импорта вида ../../../../../../script.js, но
это выглядит не очень.

Можно сделать так, чтобы webpack искал относительно заданного мной каталога, в данном
случае frontend? 

Сейчас часть конфига с resolve выглядит так:

resolve: {
        moduleDirectories: ['node_modules'],
        extension: ['', '.js', '.styl']
},




Дополнение. Импорт прошел успешно только после того, как добавил в конфиг директорию
с импортируемым скриптом:

resolve: {
    root: [
        path.resolve('./common/static/js'),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Почему добавляется в качестве корня этот каталог и не добавляется каталог, в котором
лежит конфиг?



Ошибка исправлена - неправильно записывал импорты.  Настройки вебпака из ответа Утки

 resolve: {
    root: [
        path.resolve(__dirname),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Поправил импорт

import { capitalizeFirstLetter, formatString } from 'common/static/js/common.js';
import { elementByClass, elementById } from 'common/static/js/common.js'

    


Ответы

Ответ 1



Для webpack 1 (то есть текущего стабильного документированного) нужно добавить root в секцию resolve: var path = require('path'); resolve: { root: [ path.resolve('yourRoot') ] }, yourRoot - расположение желаемого корня. Например текущую директорию для webpack.config.js можно взять так: path.resolve(__dirname) path - родной нодовский модуль, ставить отдельно не надо.

Считывание изменений содержимого файла

#cpp #qt #qt5


Некоторая программа постоянно дописывает определённое кол-во строк в N-е число файлов.
Мне необходимо в цикле проверять изменился ли файл, и если в него что-то дописали,
то считать эту информацию. Все файлы имеют обычное расширение txt. 
Существует ли уже готовое решение во фрейморке qt? так сказать "из коробки". 
    


Ответы

Ответ 1



Есть такой велосипед tail из GNU core utilities. # dpkg -S `which tail` coreutils: /usr/bin/tail Можно запустить tail -F /var/log/*.log, -F - флаг говорит утилите следить за изменениями. Таким образом Ваша задача решается. Сырцы tail на c: http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c Кошмарные конечно, но всего 2400 строк. 2234 int main (int argc, char **argv) { там заполняются хидеры( заголовки ) потом на строке 2328 for (i = 0; i < n_files; i++) ok &= tail_file (&F[i], n_units); запускается матрёшка из tail-ов на файлы, которые уже в заголовках лежат. 1885 static bool tail_file (struct File_spec *f, uintmax_t n_units) { внутри вызывается просто tail() 1871 static bool tail (const char *filename, int fd, uintmax_t n_units, uintmax_t *read_pos) там вызывается tail_lines() 1809 static bool tail_lines (const char *pretty_filename, int fd, uintmax_t n_lines, uintmax_t *read_pos) И дальше там просто lseek-ами куски вытягиваются... Вообщем, может поможет. В крайнем случае, можно запустить tail -F {Ваш,Список,Файлов} как subprocess, и ловить pipe с него...

Сортировка строк и буква ё с++

#cpp #visual_studio #строки #сортировка


Нужно отсортировать слова, например: ёжик, Азбука, аромат, Ёж. Проблема в том, что
буква ё не сортируется. 

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main() {

    int element;
    string number;
    cin >> element;
    auto l = list();
    for (int i = 0; i < element; i++) {
        cin >> number;
        l.push_back(number);
    }

    l.sort();

    for (auto iterator = l.begin(); iterator != l.end(); ++iterator)
    {
        cout << *iterator << endl;
    }


    return 0;
}

    


Ответы

Ответ 1



При сортировке списка из string строки сравниваются по-символьно (побайтно). В зависимости от типа кодирования байт будут разные результаты сравнения. Во всех популярных кодировках, а именно в Unicode, CP866 (DOS), CP1251 (Windows) во всех у них буква Ё/ё стоят где-то в отдельном месте от алфавита, это означает сравнение букв не будет давать порядок как в эталонном русском алфавите. Но проблема решаема, т.к. у функции сортировки можно указать свою функцию сравнения элементов. l.sort([](string const & l, string const & r)->bool{ /* Сравнить l и r */ }); при этом нужно реализовать код внутри так чтобы сравнить две строки l и r учитывая специфику буквы Ё/ё, код должен возвращать true если l < r иначе false. Также чтобы решить проблемы с кодировками можно просто в каком то виде вначале прочитать строки, а потом их сконвертировать в Unicode и уже в юникоде делать сравнения, либо привязаться к какой то кодировке, это не важно в какой кодировке Ё/ё по особому сравнивать. Вот привожу почти весь нужный код, подходит для строк в кодировках CP866 и CP1251 (для юникода тоже вполне может подойти только вместо char нужно uint32_t или char32_t): // Где-то выше определить функцию CharOrder. inline uint32_t CharOrder(char c) { if (c == 'ё') return uint32_t(uint8_t('е')) * 2 + 1; if (c == 'Ё') return uint32_t(uint8_t('Е')) * 2 + 1; return uint32_t(uint8_t(c)) * 2; } .... // Где нужно сортировать список l из строк, написать. l.sort([](std::string const & a, std::string const & b)->bool{ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b)->bool{ return CharOrder(a) < CharOrder(b); }); });

Ответ 2



#include #include #include #include #include #include template static void PrintList(const std::list& l) { std::cout << "List: "; for (auto iterator = l.begin(); iterator != l.end(); ++iterator) { std::cout << *iterator << " "; } std::cout << std::endl; } int main(int argc, const char * argv[]) { system("chcp 1251"); std::list l = { "ёлка", "Еда", "аббат", "жеод" }; PrintList(l); l.sort(std::locale("")); PrintList(l); return 0; }

Получение информации о функциях в модуле

#net #рефлексия #f#


Заинтересовал вопрос как получить информацию о функциях которые содержит модуль. 
Хочу получить что-то вроде того, что выдает FSI.

Например для следующего модуля

module Test = 
    let ign _ = ()
    let getNowDateTime() = System.DateTime.Now
    let getNumbers count = [1..count]


FSI выводит такую информацию

module Test = begin
  val ign : 'a -> unit
  val getNowDateTime : unit -> System.DateTime
  val getNumbers : count:int -> int list
end


Пробовал достать данные через рефлексию следующим образом

let getInfoAboutModule (t : Type) = 

    let genericToString (t : Type) = 
        match t.GenericTypeArguments with
        | [| |] -> t.FullName
        | x -> 
            x 
            |> Seq.map (fun x -> x.Name)
            |> String.concat "," 
            |> sprintf "%s<%s>" t.Name

    let getInfo (mi:MethodInfo) =
        let parameter = 
            let sb = System.Text.StringBuilder()

            for x in mi.GetParameters() do
                x.ParameterType
                |> genericToString
                |> sprintf "%s : %s ->" x.Name
                |> sb.Append
                |> ignore

            sb.ToString()
            |> fun str -> if str |> System.String.IsNullOrEmpty then "unit -> " else str

        sprintf "%s : %s %s" mi.Name parameter (genericToString mi.ReturnType) 

    t.GetMethods(BindingFlags.Public ||| BindingFlags.Static)
    |> Seq.map getInfo


для модуля Test результат будет следующим

ign : _arg1 :  -> System.Void
getNowDateTime : unit ->  System.DateTime
getNumbers : count : System.Int32 -> FSharpList`1


MCVE (ideone)

но, естественно, таким образом получаю названия далекие от F#-ных.



P.S. Добавлять какие-либо атрибуты к модулю нельзя, т.к. нужно оставить возможность
извлекать данные из модулей из других сборок.
    


Ответы

Ответ 1



Можно воспользоваться FSharp.Compiler.Service для анализа исходных текстов модулей. Если модуль скомпилирован и его исходных текстов нет, то сомневаюсь, что можно добиться лучшего результата, чем ваш. На основе этого примера: open System open System.IO open Microsoft.FSharp.Compiler.SourceCodeServices let text = """ module Test = let ign _ = () let getNowDateTime() = System.DateTime.Now let getNumbers count = [1..count] """ let checker = FSharpChecker.Create() // из примера let parseAndTypeCheckSingleFile input = let file = "test.fsx" let projOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously let parseFileResults, checkFileResults = checker.ParseAndCheckFileInProject(file, 0, input, projOptions) |> Async.RunSynchronously // Wait until type checking succeeds (or 100 attempts) match checkFileResults with | FSharpCheckFileAnswer.Succeeded(res) -> parseFileResults, res | res -> failwithf "Parsing did not finish... (%A)" res // печать информации о члене модуля let printInfo (fn:FSharpMemberOrFunctionOrValue) = // строка с информацией о типе let rec getTypeString (t:FSharpType) = if t.HasTypeDefinition then let prms = [ for x in t.GenericArguments -> (getTypeString x) ] in t.TypeDefinition.DisplayName + " " + String.Join(" ", prms) else t.ToString() printf "%s: " fn.DisplayName for group in fn.CurriedParameterGroups do for prm in group do match prm.Name with | None -> () | Some name -> printf "%s:" name printf "%s -> " (getTypeString prm.Type) printf "%s\n" (getTypeString fn.ReturnParameter.Type) [] let main argv = let parseFileResults, checkFileResults = parseAndTypeCheckSingleFile text let m = checkFileResults.PartialAssemblySignature.Entities.[0] let fns = m.NestedEntities.[0].MembersFunctionsAndValues for x in fns do printInfo x 0 Результат: ign: type 'a -> unit getNowDateTime: unit -> DateTime getNumbers: count:int -> list int Либо можно поизучать исходники непосредственно FSI. Если возникает ошибка при парсинге, нужно скопировать файлы FSharp.Core.optdata и FSharp.Core.sigdata в каталог с программой. Файлы можно найти в %PROFRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.4.0.0\.

Как чистить оперативную память сервера после выполнения php скрипта?

#php #linux #сервер #веб_сервер #memory


Проблема собственно вот в чем: мои скрипты php после отработки засоряют оперативную
память сервера,но не все конечно. Системный администратор после изучения этой темы
говорит что память засоряется после моих скриптов и они являются активными процессами(
как я понял спящими по букве S)

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

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

Или может добавлять какуюто строку кода в php скрипт чтобы сервер убивал соединение?

Да кстати в циклах использую

break;


Также использовал

ini_set('memory_limit', '1024M');


Но после закоменчивания этой строки изменений не было. Или может жестко поступить
- найти все переменные и сделать

unset($some_param);


Откуда начинать копать? Статьи по оптимизации кода читал, применяю их на практике,
но как известно в этом направлении можно далеко уйти и писать на Ассемблере

Добавлено минутой позже:

Также использую в коде 

exit();


в том случае если код не имеет смысла дальше выполнять - или вместо него необходимо
использовать 

die();


Добавлено 5 минутами позже:

Это веб сервер.
Пользователь загружает фаил эксель для парсинга и получается вышеописанное
NGINX 1.6.2 PHP5-FPM без APACHE
5.6 PHP версия

Добавлено через 9 часов:

на форуме говорится о команде 

strace -p 


которая показывает что хочет выполнить процесс в нашем случае PID 10354. Это конечно
не ответ на вопрос, но может поспособствовать его решению.

На ресурсе сказано что данный режим может быть вызван недостатком мощностей процессора(но
по сути какой бы мощный процессор не был, нагрузить его на 100% можно), также сказано
что такое поведение наблюдается когда в коде php есть команда

sleep($count_of_seconds);


Да - данная команда ввергает процесс в состояние Sleep, но здесь нет зависимости
от количества потребляемой памяти.

Как мне объяснил системный администратор - сколько пользователей на сайте, столько
будет спящих www-data, следовательно состояние sleep вполне нормально, ненормально
количество удерживаемой для этого процесса памяти.

Добавлено 22,02,2017

Вот что происходит когда остаются 3 спящих процесса


    


Ответы

Ответ 1



Моя история похожа. Конфигурация: nginx+php-fpm Тяжелый запрос на бекенде и при заходе на него 3-5 раз подряд, память забивалась и вылетала ошибка: 502 bad gateway При этом память сама не отчищалась. Мой конфиг до проблемы: pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 25 pm.max_requests = 500 Конфиг после: pm = dynamic pm.max_children = 10 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 5 pm.max_requests = 500 Попробуйте так.

Ответ 2



Считаю 374 мегабайта RES совершенно нормальным значением для php-fpm. То есть, на мой взгляд, у вас проблема совершенно не в вашем коде, а либо в использовании PHP как такового, либо просто в неадекватной задачам конфигурации сервера (мало RAM для запущенного набора процессов).

Ответ 3



Тут оказывается не только дело в скриптах но и в настройках php-fpm а именно надо поиграться с настройками /etc/php5/fpm/pool.d/www.conf а именно pm.max_requests request_terminate_timeout request_terminate_timeout устанавливает максимальное время выполнения дочернего процесса, прежде чем он будет уничтожен. Это позволяет избегать долгих запросов, если по какой-либо причине было изменено значение max_execution_time в настройках интерпретатора. Значение стоит установить исходя из логики обрабатываемых приложений, скажем 60s (1 минута).

Установка pickle

#pip


В консоле windows ввожу команду pip install cpickle 

Collecting cpickle
  Downloading cpickle-0.5.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "", line 1, in                                       
                                             
      File "c:\users\kaz19\appdata\local\programs\python\python35\lib\tokenize.py",
line 454, in open                           
        buffer = _builtin_open(filename, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\kaz19\\AppData\\Local\\Temp\\pip-build-nnts2rx3\\cpickle\\setup.py'


Как это исправить?
    


Ответы

Ответ 1



Оказывается в python 3.5 он уже установлен и называется просто pickle

CSS Границы элемента при его трансформации

#css #css3


Здравствуйте.
Если к элементу применить CSS свойство transform: rotate(45deg) он развернется, но
положение в потоке не изменит 



Возможно ли сделать так, чтобы границы блока пересчитались и рассчитывались по углам,
например так:


    


Ответы

Ответ 1



Вызов .getBoundingClientRect() всегда возвращает актуальные габариты элемента, в т. ч. после трансформации. Нам понадобятся его свойства width и height. Чтобы центр вращения всегда был внутри внешней обертки нам надо выровнять его по вертикали и горизонтали, для этого поставим обертке свойство display: inline-flex, а самому элементу margin: auto. Далее, при каждом вращении будем устанавливать ширину и высоту вращаемого элемента обертке. let rotationAngle = 0, el = document.querySelector('.el'), wrapper = document.querySelector('.wrapper'); recalcDimensions(30); document.querySelector('.rotator').addEventListener('click', recalcDimensions.bind("", 5)); function recalcDimensions(rotateAngle) { rotationAngle += rotateAngle; el.style.transform = "rotate(" + rotationAngle + "deg)"; let w = el.getBoundingClientRect().width, h = el.getBoundingClientRect().height; wrapper.style.width = w + 'px'; wrapper.style.height = h + 'px'; } .wrapper { display: inline-flex; background-color: #000; position: relative; } .el { display: block; margin: auto; width: 250px; height: 250px; background-color: #ccc; } .rotator { position: absolute; right: 10px; top: 10px; padding: 10px 20px; }


Ответ 2



div { position: relative; } div::after, div::before { content: ''; display: block; position: absolute; top: 0; left: 0; width: 200px; height: 200px; } div::after { background-color: rgba(0, 255, 0, .3); } div::before { background-color: rgba(0, 0, 255, .3); transform: rotate(45deg) scale(.70711356, .70711356); }


Передача интерфейса из dll в основное приложение

#c_sharp #aspnet #dll


Добрый день. Мне нужно из моей dll передать объект класса, реализующего такой интерфейс:

public interface IDataProvider
{
    void InitPhone();
    List GetPhone();
    string Print();
}


передать в мое основное приложение. В основном приложении я так же описал данный
интерфейс. В dll написан вот такой код который возвращает реализацию данного интерфейса:

public class CreateInstance
{
    public IDataProvider GetDataProvider()
    {
        IDataProvider provider = new DataProvider();
        return provider;
    }
}


А в основном приложении данная библиотека подключается при помощи assembly meneger
и вызывается, таким вот образом:

public class DataModuleInterface
{
    Object o;
    Type t;
    Assembly ass;
    public DataModuleInterface()
    {
        var binFolder = new DirectoryInfo(Path.Combine(@"C:\Users\Neoniklain\Source\Repos\KemSU_Shedule\Shedule\Shedule\Modules"));

        foreach (var file in binFolder.GetFileSystemInfos("*.dll", SearchOption.AllDirectories))
        {
            ass = AssemblyLoadContext.Default.LoadFromAssemblyPath(file.FullName);
            Type[] AssemlyResource = ass.GetExportedTypes();
            Type type= AssemlyResource[0];
            foreach (var item in AssemlyResource)
            {
                if(item.Name=="CreateInstance")
                {
                    t = ass.GetType(item.FullName);
                }
            }
            o = Activator.CreateInstance(t);
        }
    }

    public IDataProvider GetProvider()
    {
        MethodInfo m = ass.GetType(t.ToString()).GetMethod("GetDataProvider");
        IDataProvider res = (IDataProvider)m.Invoke(o, null);
        return res;
    }
}


Ошибка возникает вот в этом месте: 

IDataProvider res = (IDataProvider)m.Invoke(o, null);


И содержит следующий текст: 

System.InvalidCastException: 
"Unable to cast object of type 'Shedule.Module.DataModule.DataProvider' 
to type 'Shedule.Module.DataModule.IDataProvider'."


Здесь стоит сказать что hedule.Module.DataModule - это моя библиотека, из которой
я хочу получить тот самый злосчастный класс.
    


Ответы

Ответ 1



В основном приложении я так же описал данный интерфейс. У Вас определение интерфейса существует в двух местах, что для .NET означает два разных типа. Поместите тип интерфейса в третью библиотеку и ссылайтесь на нее из первых двух. P.S. А кто из присутствующих когда-нибудь получал такое сообщение об ошибке: Cannot assign TFont to TFont. ?

Верстка каркаса html шаблона

#html #css #вёрстка


Такая проблема, есть макет https://jsfiddle.net/61htzzrx/



header {
  background-color: #FBD293;
  border-bottom: 1px solid #000;
  height: 50px;
}
.middle {
  border-right: 1px solid #000;
  margin: 0 auto;
  min-height: calc(100% - 50px);
  overflow: hidden;
  position: relative;
  width: 600px;
  background-color: #fff;
}
.middle > .left-sidebar {
  background-color: #CBE6A3;
  border-right: 1px solid #000;
  box-sizing: border-box;
  display: block;
  float: left;
  min-height: calc(100vh - 50px);
  padding-bottom: 160px;
  width: 100px;
}
.left-sidebar > .blocks {
  background: #e6a3a3;
  height: 400px;
}
.middle > .content {
  background: #A3CCFF;
  display: block;
  float: left;
  min-height: calc(100vh - 50px);
  width: 500px;
}
.left-sidebar footer {
  height: 100px;
  bottom: 0;
  position: absolute;
  background: #D6A3E6;
}
Контент, должен быть прижат к низу





















































Надо прижать .content к низу и сделать так, чтобы меню всегда оставалось на виду (перемещалось вместе с прокруткой) Сейчас у меня такие проблемы: 1) Черная полоска справа от aside идет не до конца страницы, и фон aside тоже 2) .blocks должен прокручиваться вместе со страницей и не залезать на footer


Ответы

Ответ 1



Сайдбар клеится внутрь блока при помощи position: sticky, для кроссбраузерности не забудьте использовать полифилл. Остальное — флексбокс. *, *:after, *:before { box-sizing: border-box; } body { display: flex; flex-direction: column; align-items: center; } header { background-color: #FBD293; border-bottom: 1px solid #000; height: 50px; width: 600px; } .middle { border-right: 1px solid #000; margin: 0 auto; width: 600px; background-color: #fff; display: flex; flex-grow: 1; } .left-sidebar { position: relative; background-color: #CBE6A3; border-right: 1px solid #000; display: flex; flex-direction: column; flex-basis: 100px; } .left-sidebar__blocks-holder { position: relative; flex-grow: 1; } .blocks { background: #e6a3a3; height: 400px; position: sticky; top: 0; } .content { background: #A3CCFF; min-height: 800px; flex-grow: 1; } .left-sidebar footer { height: 100px; background: #D6A3E6; }
Контент, должен быть прижат к низу


Ответ 2



Вот пример по тем критериям которые вы сказали что хотите поправить: Это стандартная верстка CSS не знаю что объяснить, если будут вопросы скажите. Вот код: body{ margin: 0; } header { background-color: #FBD293; border-bottom: 1px solid #000; height: 50px; } .middle { border-right: 1px solid #000; margin: 0 auto; min-height: calc(100% - 50px); overflow: hidden; position: relative; width: 600px; background-color: #fff; } .middle > .left-sidebar { position: fixed; top: 0; z-index: 1000; background-co background-color: #CBE6A3; border-right: 1px solid #000; box-sizing: border-box; display: block; width: 100px; height: 100%; } .left-sidebar > .blocks { background: #e6a3a3; height: 100%; } .middle > .content { position: relative; background: #A3CCFF; display: block; float: left; min-height: calc(100vh - 50px); width: 500px; padding-left: 100px; padding-bottom: 50px; } .content_footer{ position: absolute; bottom: 0; width: 100%; height: 50px; background: yellow; } body>footer { height: 100px; background: #D6A3E6; }
Футер
всегда внизу


Как правильно задать лицензию LGPL для релизной программы на Qt?

#cpp #qt #qt5 #лицензирование


Просто хочу узнать правильно ли я думаю. Допустим я создал релизный exe файл, разместил
нужные Qt библиотеки для запуска в папке. Программа под лицензией LGPL. Я кидаю в папку
проги файл лицензии LICENSE.txt c описанием лицензии http://www.gnu.org/licenses/lgpl.html . 


Достаточно этого чтобы распространять прогу?
Я хочу добавить еще свои условия дополнительно, например:
"Данное програмное обеспечение используется вами на свой страх и риск. Автор не несет
ответственности за возможные нежелательные последствия в случае применения данного
програмного обеспечения." Ну я еще хочу написать что то типа что доступ к вашей файловой
системе не будет использован хакерами и т.д.
Я конечно все переведу на English. Так вообще правильно? 
И Inno Setup делаю установщик с файлом этой лицензии.

    


Ответы

Ответ 1



Достаточно этого чтобы распространять прогу? Недостаточно. Коротко по пунктам: Qt использует не LGPL, a LGPLv3 - это важно! Согласно п.4 LGPLv3, кроме помещения текста оригинальной (без перевода) лицензии - нужно в исполняемый файл добавить ссылку/пункт, в котором есть упоминание об использовании библиотеки и лицензии, а так же ссылку/пункт, по которому текст лицензии будет доступен из приложения. Обычно это делается в диалоге "О программе". А лучше самостоятельно изучить этот пункт лицензии и выполнить все его требования, там их немного. Можно распространять программу по нескольким лицензиям одновременно, например, LGPLv3 и вашей собственной. Но следует учесть, что вы должны обеспечить отсутствие конфликтов лицензий. Иными словами, не должно быть ни одного взаимоисключающего требования между всеми лицензиями одновременно. Тем не менее, запрещать допущения из других лицензий (налагать свои непротиворечащие требования) - вы вправе. Я конечно все переведу на English Свою лицензию вы вольны оставлять на любом языке. Но есть нюанс. Действующей лицензией считается только лицензия на одном языке (это орининал). Какой это будет язык - решать вам.

Vector, Hashtable. В чем минус синхронизированности?

#java #коллекции #concurrency


Vector, HashTable, Stack являются устаревшими коллекциями, и пишут что их не используют
в виду синхронизированности их методов. В чем минус синхронизации? Если однопоточная
среда, это как-то влияет на их работу? Потокобезопасность это же хорошо. Если они устаревшие,
зачем создавали синхронизированные коллекции в concurrent пакете? 
Извините за тупой вопрос, очень интересно просто. Заранее спасибо.
    


Ответы

Ответ 1



Потокобезопасность это же хорошо. Потокобезопасность не бесплатна, точнее очень не бесплатна, именно поэтому есть потокобезопасные и не потокобезопасные коллекции. Если однопоточная среда, это как-то влияет на их работу? Такие коллекции работают значительно медленее, чем не синхронизированные аналоги Если они устаревшие, зачем создавали синхронизированные коллекции в concurrent пакете? Новые синхронизированные коллекции используют более быстрый алгоритм, когда блокируется не вся коллекция целиком при каждом чихе, а только часть (блок), поэтому Vector, HashTable, Stack не стоит использовать ни в многопоточности (они работают медленнее, чем новые коллекции), ни в однопоточном - они просто избыточны. Если интересно более подробно разобраться с коллекциями советую посмотреть мою статью P.S. В принципе, если вам производительность не важна, то ничего страшного не случится если вы будите использовать Vector, HashTable и т.п. вместо ArrayList, HashMap и т.д., они будут работать нормально. Но их использование считается плохим кодом и признаком плохого знания языка.

Проверка на гласные и согласные буквы

#javascript #jquery


Если встречается согласная буква, то пропускать одну позицию в строке, если встречается
гласная - то две.
В итоге должно получится слово hello. Проблема в том, что значение в pos после первого
раза не меняется, как это поправить?



var str = "hieeelalaooo"; //строка
var vowels = "aeiouy"; //гласные
var pos=0, res;
var res = str.charAt(0);
for (var i = 0; i <= str.length; i++) {
  for (var j = 0; j <= vowels.length; j++) {
    if (pos == i) continue;//если есть позиция букву которой мы взяли то пропускаем 
    if (str[i] != vowels[j]) {//если согласная то 
      pos = i + 2;//позиция увеличивается на два
    } else {
      pos = i + 3;//если гласная то на три
    }
  }
  res += str[pos];//получаем букву
  console.log(res)
}



    


Ответы

Ответ 1



Наличие символа в массиве гласных можно делать с помощью indexOf, т.е. по факту вам не нужны 2 цикла с тремя счетчиками. var str = "hieeelalaooo"; //строка var vowels = "aeiouy"; //гласные var pos, res = ""; var i = 0; while (i < str.length) { res += str[i]; if(vowels.indexOf(str[i]) > -1) { i += 3; } else { i += 2; } } console.log(res);

Ответ 2



Ошибка в логике: вместо того, чтобы определить гласная буква или согласная, на каждую букву pos меняется столько раз, сколько букв в массиве vowels Кроме этого: проблемы со счетчиками (i <= str.length;, j <= vowels.length;) - в случае когда счетчик равен str.length, str[i] будет равен undefined, так как индексация идет с нуля. строка res меняется после изменения pos, но до проверок, что pos не выходит за границы строки. Поэтому в конце результата выводится много undefined if (pos == i) continue; - бесполезное условие, которое всегда false непонятно как связан счетчик i с переменной pos. Если убрать недочеты, то может получиться так: // Если встречается согласная буква, то пропускать одну позицию в строке, если встречается гласная - то две. var str = "hieeelalaooo"; //строка var vowels = "aeiouy"; //гласные var res = ''; for (var pos = 0; pos < str.length;) { res += str[pos]; var isVowels = false; for (var j = 0; j < vowels.length; j++) { // проверяем тип буквы if (str[pos] == vowels[j]) { // если гласная isVowels = true; // выставляем флаг break; // выходим } } if (isVowels) { pos += 3; } else { pos += 2; } console.log(res) } вместо внутреннего цикла, можно воспользоваться методом indexOf как в ответе @br3t либо перевести строку в объект, с ключами соответствующими гласным буквам и использовать его: // Если встречается согласная буква, то пропускать одну позицию в строке, если встречается гласная - то две. var str = "hieeelalaooo"; //строка var vowels = "aeiouy".split('').reduce((acc, el) => acc[el] = true && acc, {}); //гласные var res = ''; for (var pos = 0; pos < str.length;) { res += str[pos]; if (vowels[str[pos]]) { pos += 3; } else { pos += 2; } console.log(res) }

Ответ 3



var str = "hieeelalaooo"; //строка var vowels = "aeiouy"; //гласные var vowels = new Set(vowels.split('')); var res = ''; for (var i = 0; i < str.length; i++) { if (str[i] === ' ') res += str[i++]; res += str[i]; i = vowels.has(str[i]) ? i + 2 : i + 1; } console.log(res);

Ответ 4



var str = "hieeelalaooo"; var vowels = 'aeiouy'; var word = ''; for (var i = 0; i < str.length; i++) { if (str[i] == ' ') { word += ' '; } else if(vowels.indexOf(str[i]) > -1 ) { word += str[i]; i += 2; } else { word += str[i]; i++; } } console.log(word);

Ответ 5



=> что-то типа того, осмысленней и по-современней, чем предлагали выше: { const str = "hieeelalaooo"; //строка const glass = "aeiouy"; //гласные const res = []; str.split('').forEach(e=> glass.split('').includes(e) && !res.includes(e) ? res.push(e):'' ) console.log('гласные не повторяющиеся -> '+res.join('')); } ///////еще короче: { const str = "hieeelalaooo"; //строка const glass = "aeiouy"; //гласные str.split('').reduce( (sum,e) =>glass.split('').includes(e) && !sum.includes(e) && sum.push(e)&&sum||sum, [] ) }

Dictionary and custom pair [дубликат]

#c_sharp


        
             
                
                    
                        
                            This question already has answers here:
                            
                        
                    
                
                        
                            Составной ключ в Dictionary
                                
                                    (4 ответа)
                                
                        
                                Closed 2 года назад.
            
                    
public class Pair
{
    public FT x;
    public ST y;
    public Pair()
    { }
    public Pair(FT a, ST b)
    {
        x = a;
        y = b;
    }
}
Dictionary,int> used = new Dictionary, int>();


Есть код выше. Я добавляю в used данные таким образом   

used[new Pair(x, y)] = 1;


И когда хочу проверить used.ContainsKey(new Pair(x, y)), то всегда выдается
false, даже тогда, когда такие же x,y уже есть. Просто добавляются еще раз. С чем это
может быть связано?
    


Ответы

Ответ 1



Dictionary для того, чтобы обращаться к элементу по ключу, необходимо сравнивать ключи друг с другом. Вы должны реализовать операцию сравнения двух объектов класса Pair, например, реализовав интерфейс IEquatable>, либо, переопределив метод object.Equals и object.GetHashCode. Пример реализации IEquatable>: public class Pair : IEquatable> { private FT x; private ST y; public Pair() { } public Pair(FT a, ST b) { x = a; y = b; } public bool Equals(Pair other) { return EqualityComparer.Default.Equals(x, other.x) && EqualityComparer.Default.Equals(y, other.y); } public override bool Equals(object other) { if (other is Pair) return Equals((Pair)other); return false; } public override int GetHashCode() { return EqualityComparer.Default.GetHashCode(x) ^ EqualityComparer.Default.GetHashCode(y); } } Тонкий момент заключается в том, что эта операция сравнения не будет работать, если у типов FT и ST также нет реализации IEquatable или не переопределён метод object.Equals. UPDATE Как здесь ниже справедливо дописали в комментариях, при реализации IEquality Microsoft рекомендует также переопределить методы Equals и GetHashCode, а также операторы == и !=. Так что самый дешёвый способ, это переопределить методы Equals и GetHashCode. Добавил изменения в код.

Как перебрать все свойства объекта, преобразовать их неким образом и вернуть преобразованный объект?

#javascript


Как перебрать все свойства объекта, преобразовать их неким образом и вернуть преобразованный
объект?

есть объект такой

"object": {
    "user": "admin",
    "date": "14877890",
    "last": "SKIPPED"
}


Нужно преобразовать date в дату и получить новый объект
    


Ответы

Ответ 1



Вот пример с функцией map для прохождения по объекту, и преоброзования timestamp в date var object = { "user": "admin", "date": "14877890", "last": "SKIPPED" } function timestamp2date(timestamp) { var theDate = new Date(timestamp * 1000); return theDate.toGMTString(); } Object.keys(object).map(function(objectKey, index) { var value = object[objectKey]; if(objectKey == 'date'){ console.log(timestamp2date(value)); } });

Переключение между вкладками Chrome, зная tabId этих вкладок

#javascript #google_chrome #chrome_extension


Здравствуйте. 

Хочу реализовать переключение между вкладками Google Chrome в своём расширении. Расширение
уже узнаёт id вкладок и может их обновлять. 

Возможно ли сделать переключение между необходимыми мне вкладками, зная их tabId?


    


Ответы

Ответ 1



Для этого используйте updateProperties в методе .update(): chrome.tabs.update(tabId, { active: true });

Ломаю голову, контроль пути

#cpp #boost #геолокация


Имеется прорисовка пути маршрута автобуса выполненная при помощи массива точек (широта,
долгота) которые затем через leaflet прорисовываются у клиента

Делалось это все просто для визуального отображения маршрута в GPS мониторинге.
Теперь понадобилось контролировать съезд с маршрута как можно менее затратно в плане
ресурсов.

План таков, преобразовать каким то образом трансформировать точки в полигон и уже
через boost::geometry::intersects сверять находится ли машина на маршруте или нет при
поступлении свежих координат.

Идея по трансформации только такая, брать 2 точки добавлять по 10 метров отступа
слева и создавать полигон.

Проблема в том что точек на маршруте бывает под 1000..сомневаюсь что работать будет
быстро..может как то можно отсеять лишние точки

Ломаю голову..

Может есть что то готовое для подобной задачи?

Прошу помощи
    


Ответы

Ответ 1



А зачем возиться с полигонами? У вас есть массив точек маршрута. Каждая пара соседних точек определяет отрезок, часть маршрута. Определить, к какому отрезку ближе всего точка Вычислить кратчайшее расстояние до него (длинна перпендикуляра) Если оно больше максимального заданного расстояния Lmax - зафиксировать съезд с маршрута

Что делает vctip.exe?

#windows #visual_studio #visual_cpp


Чисто случайно обнаружил, что среди сообщений об ошибках Windows много ошибок vctip.exe.
Начал копать, выяснил, что это что-то в составе Visual C++ 2015, но что эта программа
делает - в Интернете не пишут (или я не нахожу). Подсунул вместо нее заглушку - ей
не передается никакая информация (ни в командной строке, ни через стандартный ввод).
Вызывается при компиляции, но самой компиляции не мешает.

Стало просто интересно. Кто-то может подсказать, что это и зачем?

PS

File   : vctip.exe
SHA256 :  46f89793d5df3ca4a24e1b1ee196ea150b105a7e10947c57e336509a12731c2f
SHA1   :  3648f03dc77946835fce7b54f358434a6f13bbc3
MD5    :  fd442c307bc454d3930eaf6ec878fd36
CRC32  :  cfa16112

    


Ответы

Ответ 1



Согласно данному ответу на форуме поддержки, это клиент телеметрии, который отправляет в Microsoft сведения о выполняемых в студии действиях и возникающих ошибках (Visual Studio Customer Experience Improvement Program). Ему ничего не передается через командную строку, потому что он берет всю информацию в режиме реального времени из Event Tracing for Windows. Visual Studio Customer Experience Improvement Program по умолчанию включена, но ее можно отключить способом, описанным здесь: В меню выбрать Справка -> Отправить отзыв -> Параметры. Выбрать параметр "Нет, я не хочу участвовать"

Способ расширения/наследование/декорирования 2D массива

#c_sharp #c_sharp_70


Существует ли какой-либо способ расширить встроенный прямоугольный массив в c#?
Например:

public class Array2D:????
{
    private T[,] _data;

    public Array2D(T[,] vals)
    {
        _data = vals;
    }

    public IEnumerable Row( int iRow)
    {
        return _data.Cast().Select((t, j) => _data[iRow, j]);
    } 
}

    


Ответы

Ответ 1



Использовать методы расширения? public static class TwoDimensionalArrayExtensions { public static IEnumerable Row(this T[,] array, int iRow) { if (array == null) { throw new ArgumentNullException(nameof(array)); } if (iRow < array.GetLowerBound(0) && iRow > array.GetUpperBound(0)) { throw new ArgumentOutOfRangeException(nameof(iRow)); } for (int columnIndex = array.GetLowerBound(1); columnIndex <= array.GetUpperBound(1); columnIndex++) { yield return array[iRow, columnIndex]; } } } Использование: static void Main(string[] args) { var array = new int[2, 2] { { 1, 2 }, { 3, 4 } }; foreach (var value in array.Row(0)) { Console.WriteLine(value); } }

Доступ к структуре через unsigned char

#cpp #language_lawyer


Пусть есть структура S следующего вида:

    struct S 
    {
        short a;
        char b;
    };


И размер sizeof(short) равен 2, а размер sizeof(S) равен 4 (т.е. в структуре есть
один padding byte).

Вопрос 1. Является ли корректным с точки зрения стандарта языка такой код:

    S st;

    st.a = 0; st.b = 0;
    unsigned char *p = reinterpret_cast(&st);
    for (size_t i = 0; i != sizeof(st); ++i)
        unsigned int tmp = p[i];


Вопрос 2. Если код корректен, то гарантируется ли, что в ситуации, когда указатель
p указывает на padding byte структуры S, в переменную tmp будет записано некоторое
целочисленное значение из отрезка [0; UCHAR_MAX] или допускаются какое-нибудь менее
очевидное поведение, например, генерация исключения.



Дополнение.   

Действительно, если есть объект тривиально-копируемого типа T, то составляющие его
байты могут быть безопасно скопированы (например, с помощью memcpy) в массив char,
unsigned char или std::byte (и обратно). Также можно скопировать некоторый объект тривиально-копируемого
типа в другой объект этого же типа (с помощью того же самого memcpy, например.)

Однако, в пункте 11.6/12 (n4659) есть занятный пример:

    unsigned char c;
    unsigned char d = c; // OK, d has an indeterminate value
    int e = d; // undefined behavior


Не является ли мой пример, в некотором смысле, эквивалентом этого примера из стандарта?
    


Ответы

Ответ 1



1) Да, каст к char* и unsigned char* разрешен (а каст к другим типам запрещен правилами aliasing) 2) Нет для int. Паддинг можно читать-писать (иначе memcpy сломался бы). Однако, стандарт разрешает читать indeterminate value типа [unsigned] char в присваиваниях где левая стророна это l-value типа [unsigned] char, но запрещает присваивать например int. (При этом неясно, считается ли что паддинг может иметь indeterminate value)

Отсортировать SQL выдачу

#mysql #sql


Добрый день, можете подсказать как мне отсортировать выдачу MySQL по количеству совпадений?
К примеру есть запрос 

SELECT * FROM `content` WHERE `text` LIKE "%hi%" AND `text` LIKE "%bro%"


Надо сделать так, что бы выдача была по убыванию ( то бишь там где больше всего bro
и hi - самое первое, где меньше всего - самое последнее ). Заранее спасибо!
    


Ответы

Ответ 1



SELECT *, (length(text) - length(replace(text,'hi','')) / 2) + (length(text) - length(replace(text,'bro','')) / 3) AS OrderField FROM content WHERE text LIKE "%hi%" AND text LIKE "%bro%" ORDER BY OrderField

Как создать гибкую схему таблиц для хранения сообщений из разных чатов?

#mysql #data_structures


Помогите пожалуйста разобраться в следующей ситуации:

Есть два вида API где хранятся истории сообщений, это Zopim и Chat2Desc(импортировать
в Postman) . Пока эти два но могут потом и другие появится.

И моя ДБ с таблицей users:

Table users
id , email, phone, ...


В Zopim пользователи идентифицируются через email, a в Chat2Desc через телефон. Для
меня эти два поля важны, какой бы чат  не был и сколько бы их не было.

То есть если я получаю емайл либо телефон пользователя в сообщениях, то делаю запрос
в свою базу (table users) для идентифицирования своего пользователя.

Да и в принципе даже структура чатов не важна, я данные как нибудь да выберу.А вот
как их правильно сохранить , да так чтоб у меня была одна структура для всех .

И вот что я придумал:


Разъяснение:

Таблица chats (Данные для чата) :


client_id   - указывает на id таблицы chat_clients
duration    - длительность чата
system_type - хранит имя чата (Zopim, Chat2Desc, ... )
created_at  - дата создания 


Таблица chat_clients (сведений об пользователей которые были в чате):


assigned_data - те инициалы под которыми пользователи были в чате
is_agent      - (0 | 1): 1 => мой пользователь, 0 => не мой
users_id      - id пользователя. Содержит либо id из таблицы users либо пустой.
bean_module   - неважно (сведение о моём пользователе)
unique_col    - Тут будет либо email (из Zopim) либо телефон (из Chat2Desc, Либо
думаю хранить id таблицы users).Будет гарантировать уникальность значений.


Связка users_id + unique_col уникальна (UNIQUE KEY user_id_unique_col_UQ (user_id,unique_col))

Таблица chat_messages:


text      - текст сообщения.
client_id - указывает на id таблицы chat_clients
chat_id   - указывает на id таблицы chats
file_id   - указывает на id таблицы chat_files
transport - значение будет для Chat2Desc (Viber, WhatsApp ,...), для Zopim ,чтоб
не пустовал , Zopim


Таблица chat_files Сведения о переданных файлах в чате.Aналогичных таблиц может быть
может нет для хранения дополнительной инфы.


  Доп инфо: В дальнейшем собираюсь для каждого пользователя выводит
  историю сообщений.


Вопрос:
Как создать гибкую схему таблиц для хранения сообщений из разных чатов ?

Заранее благодарю.
    


Ответы

Ответ 1



Любые проблемы по созданию БД нужно разбивать на две части: Нужно выделить то, что уже есть. Выделить данность, реальность. То, что вы не можете изменить. То есть, выделить структуру внешних данных. Нужно выделить то, что вы хотите получить. Желаемый вид и форма. У вас в структуре всё в одной куче. И материальное представление, и логический вид. Вам нужно выделить отдельные структуры под хранения данных из каждой отдельной системы чатов, которые вы поддерживаете. Так как структуры от­личаются ключами привязки к пользователям, это должны быть разные структуры. Нет, ко­не­чно, можно всё сделать в одной таблице, но тут вы ничего не приобретёте, но очень про­иг­ра­ете в сложности структуры. Если вам нужно делать уникальный ключ по двум ко­лонкам, то вы что-то делаете не так. Затем нужно выделить то, что вы хотите получить. Значить вам нужна какая-то таблица свя­зки чатов и пользователей, и таблицы связки чатов в основной таблице и чатов в мате­риаль­ных таблицах. Если нужно хранить сообщения в каждом чате для быстрого доступа, то лучше будет это сделать явно, в отдельной таблице, не связанной с материальным пред­став­лением. Так сообщения будут храниться два раза, но вы не будете связаны материальным пред­став­лением после импорта сообщений, и ваш код получения данных из БД будет много проще и надёжней. В современном мире нет смысла пытаться оптимизировать число таблиц в БД: если у вас их будет десять или сотня, само по себе это нисколько не повлияет на скорость работы с БД. Другое дело что сложная для понимания структура БД будет отнимать ваше время и на первоначальную разработку, и на дальнейшую поддержку. Если траты вашего времени можно избежать, то это следует сделать. Сама сложная структура БД может представлять и сложность при масштабировании. Например, шардинг и уникальные индексы идут по разные стороны улицы: вы не можете использовать шардинг одновременно с уникальными индексами. То же можно сказать про скорость вставки записей: уникальные индексы ей не помогают.

Ошибка размерности массива в Python

#python #python_3x #нейронные_сети #numpy #keras


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

import numpy as np
from keras.utils import np_utils
from keras.models import model_from_json
from keras.preprocessing import image
import matplotlib.pyplot as plt
%matplotlib inline

json_file = open("fully_mesh_network.json", "r")
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("fully_mesh_network.h5")

loaded_model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

img_path = '2.png'
img = image.load_img(img_path, target_size=(28,28), grayscale=True)

x = image.img_to_array(img)
x = 255 - x
x/= 255
x = np.expand_dims(x, axis = 0)

prediction = loaded_model.predict(x)
prediction = np_utils.categorical_probas_to_classes(prediction)
print(prediction)
---------------------------------------------------------------------------

ValueError: Error when checking : expected dense_1_input to have 2 dimensions, but
got array with shape (1, 28, 28, 1)

    


Ответы

Ответ 1



Судя по ошибке ваша модель ожидает 2D массив на входе. попробуйте так: x = x.reshape(28, 28) PS метод np_utils.categorical_probas_to_classes() - отсутствует в современных версиях Keras. Вместо него можно попробовать использовать метод: keras.utils.to_categorical()

Как подгрузить много фотографий (их имена) в массив, чтобы потом использовать в html?

#javascript #html


Имеется HTML, имеется JavaScript, который создает элементы в HTML.

Также имеется куча фотографий, которые будут подгружаться в HTML. 

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

Нашел как в JavaScript подключить require('fs'), но нельзя ведь в HTML использовать
require.
    


Ответы

Ответ 1



Не совсем понятен контекст. На сколько я подозреваю, у вас только фронт-енд. require и библиотека fs - это из Node.js. Предположу, что ваши фото хранятся в папке img, рядом с index.html и вы имеете следующую структуру проекта: . ├── img | ├── image1.png | └── image2.png ├── script.js └── index.html В этом случае, вы можете использовать файлы изображений указав относительный (относительно index.html) путь к ним. Например: name Но в этом случае вам нужно в вашем script.js заранее создать массив с путями ко всем картинкам, чтобы потом в цикле их добавить на страницу. Как я понимаю, в этом и проблема. Чтобы получить имена файлов всех изображений в папке, вам нужно создать сервер на Node.js, потому что это будет работа с файловой системой. А тут уже вариантов реализаций может быть много, но схема будет приблизительно такая: Запускается Node.js сервер, который будет работать как процесс на вашем компьютере; В браузере вы откроете страницу http://localhost, где будет отрисован ваш index.html (сервер отправит этот файл в браузер); Перед отдачей браузеру файла index.html вы можете его модифицировать, и поместить в него заранее массив путей ко всем изображениям. Это обширная тема, и я не могу тут описать все возможные варианты реализаций начиная от установки Node на вашу систему, заканчивая использованием движков html шаблонов, которые (если сказать коротко) расширяют возможности обычного html. Вам следует найти информацию по созданию сервера на Node.js. Например тут: https://learn.javascript.ru/ajax-nodejs https://webref.ru/dev/first-node-app/http-server А после этого, возможно, переформулировать ваш вопрос, и описать результат, который вам нужен.

функция давления кирпича пирамиды

#алгоритм #математика #любой_язык


Есть двумерная пирамида из кирпичей. Вес 1го - 1 кг, давит равномерно на 2 под ним
по 0.5кг.
То есть, если на верхний давит +100 кг, тогда под ним на каждый будет (100+1)/2 кг
- на нижний давит пол веса каждого над ним.

1,0=.5 2,0=.75 2,1=1.5 3,0=.875 3,1=.2.125

Как вычислять давление на любой из них, указывая позицию, например, к4-2, к8-4 ...
к(рядСверху,номерСлева) - как функция с 2 параметрами, возвращающая вес?

Думал, pяд*.5 + (pяд-1)/2 или 1*(c+1) / 2*p + 1*c / 2*p, разные другие варианты,
но никак не могу подобрать точный. (желательно на java)
    


Ответы

Ответ 1



А почему не воспользоваться рекурсией? Значения веса, номер ряда и номер кирпича в ряду вставляйте какие вам надо: public static void main(String[] args) { float weight = 1; //вес кирпча int row = 5; //номер ряда начиная с 1 с верху int num = 3; //номер кирпича слева (или с права, как больше нравится) с 1 System.out.println(pressueOnBrick(row, num, weight)); } //давление на один кирпич public static float pressueOnBrick(int row, int num, float weight) { return pressue(row, num, weight) - weight; //давление оказываемое на один кирпич = полное //давление которое оказывает кирпич минус вес кирпича } //полное давление оказываемое кирпичём (включая свой вес) public static float pressue(int row, int num, float weight) { //в ряду не может быть кирпичей с номером меньше 1 и больше чем номер ряда(число кирпичей в ряду = номеру ряда) if (num < 1 || num > row) { return 0; } //давление которое оказывает кирпич равно сумме веса кирпича и половине веса кирпичей которые давят на него //слева и справа return weight + (pressue(row - 1, num - 1, weight) + pressue(row - 1, num, weight)) / 2; } Валидация вводимых значений на вашей совести.

Ответ 2



#include #include int main() { unsigned ranks{}; std::cin >>ranks; // общее количество рядов double weight{}; std::map loads; unsigned k{1}; for (; k <= ranks; ++k) { loads.insert(std::make_pair(k, weight)); weight = (weight + 1)/2; } std::cout << std::endl << "вводим нужный ряд: " << std::endl; std::cin >> k; std::cout << "нагрузка для кирпичей " << k << " - го ряда: " << loads[k]; return 0; } После обсуждения с goldstar_labs пришел к выводу переписать, поскольку первый вариант верный для двух рядов и для крайных кирпичей #include #include using std::vector; using std::cin; void setValue(const vector& p1, vector& p2) { size_t k = p2.size(); if (k <= 2) return; for (size_t i = 1; i < k - 1; ++i) p2[i] += (p1[i] + 1)/2; } int main() { unsigned ranks{}, k{}; cin >>ranks; // общее количество рядов double w{}; vector< vector > weights; for (unsigned n = 1; n <= ranks; ++n) { vector v(n, w); weights.emplace_back(v); if (n > 2 ) setValue(weights[n - 2], weights[n - 1]); w = (w + 1)/2; } std::cout << std::endl << "вводим нужный ряд: " << std::endl; std::cin >> k; k %= ranks + 1; std::cout << "нагрузки для кирпичей " << k << " - го ряда:\n"; for (double d : weights[k - 1]) std::cout << d << ' '; return 0; } Выводить, думаю вы сами сможете в желаемом формате