Страницы

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

четверг, 9 января 2020 г.

Окно подтверждения при перезагрузке страницы

#javascript #jquery


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

Есть скрипт, который ловит все обновления страницы (при нажатии на ссылку, при обновлении
через F5, через CTRL+F5 и т.д.) и перед обновлением появляется окно с сообщением что
данные могут быть не сохранены. Нужно сделать для того, чтобы пользователь случайно
не обновил страницу когда в форме есть текст.

Нужно сделать так, чтобы при нажатии на ссылку с id="ms-submit-button" окно не появлялось.

Пробовал сделать исключение с помощью jQuery, не получилось.

function Unloader(){

var o = this;

this.unload = function(evt)
{
    var message = "Данные не будут сохранены после обновления страницы или перехода";
        if($("#taskname").val() != "" || $(".note-editable").text()) { // проверка
моих полей на пустоту
            if (typeof evt == "undefined") {
                evt = window.event;
            }
            if (evt) {
                evt.returnValue = message;
            }
            return message;
        }
    }

    this.resetUnload = function()
    {
        $(window).off('beforeunload', o.unload);

         setTimeout(function(){
            $(window).on('beforeunload', o.unload);
        }, 2000);
    }

    this.init = function()
    {

        $(window).on('beforeunload', o.unload);

        $('a').on('click', function(){o.resetUnload});
        $(document).on('submit', 'form', function(){o.resetUnload});
        $(document).on('keydown', function(event){
            if((event.ctrlKey && event.keyCode == 116) || event.keyCode == 116){
                o.resetUnload;
            }
        });
    }
    this.init();
}

$(function(){
    if(typeof window.obUnloader != 'object')
    {
        window.obUnloader = new Unloader();
    }
})

    


Ответы

Ответ 1



Я так понял, что вам нужен такой результат: function Unloader() { var o = this; this.unload = function(evt) { var message = "Данные не будут сохранены после обновления страницы или перехода"; if ($("#taskname").val() != "" || $(".note-editable").text()) { // проверка моих полей на пустоту if (typeof evt == "undefined") { evt = window.event; }; if (evt) { evt.returnValue = message; }; return message; }; }; this.resetUnload = function() { $(window).off('beforeunload', o.unload); setTimeout(function() { $(window).on('beforeunload', o.unload); }, 2000); }; this.init = function() { $(window).on('beforeunload', o.unload); // Клик на a#ms-submit-button $('a#ms-submit-button').on('click', function() { $(window).off('beforeunload', o.unload); setTimeout(function() { $(window).on('beforeunload', o.unload); }, 2000); }); $(document).on('submit', 'form', function() { o.resetUnload; }); $(document).on('keydown', function(event) { if ((event.ctrlKey && event.keyCode == 116) || event.keyCode == 116) { o.resetUnload; }; }); }; this.init(); }; $(function() { if (typeof window.obUnloader != 'object') { window.obUnloader = new Unloader(); }; });

Ссылка без подтверждения

Ссылка с подтверждением



форматированный вывод c#

#c_sharp


 Console.WriteLine("{0:f4}",c);


Как в данную строку вместо  f4  - на место 4 подставить переменную в которую будет
попадать нужное количество знаков
    


Ответы

Ответ 1



Первый параметр – обычная строка, соответственно и собрать ее можно как угодно используя какие угодно переменные, начиная с обычной конкатенации Console.WriteLine("{0:f"+i+"}",c); Заканчивая интерполированием строк, которое позволяет уйти от прямого вызова string.Format Console.WriteLine($"{{0:f{i}}}",c);

Ответ 2



Console.WriteLine(string.Format("{{0:f{0}}}", i),c);

Динамическое изменение размеров textarea под содержимое

#jquery


Всем примет! У меня есть textarea. Как мне сделать, что бы  него ширина и высота
изменялись под размер содержимого текста?

Я попробовал сделать в ширину, но вышло что-то не то. У всех знаков разная ширина
и ширина, то была слишком маленькая, то большая.



var $textarea = $('#t_a');

$textarea.on('input', function() {
  var val_length = $(this).val().length;
  
  $(this).css({width: val_length * 10});
});
#t_a {
  width: 20px; 
  height: 20px;
  min-width: 20px; 
  max-height: 20px;
}





    


Ответы

Ответ 1



Возможно что-то упустил, но как-то так: var maxWidth = 200; var maxHeight = 100; $('.demo').on('input', function(e){ // Если появляется скролл и его ширина больше клиентской → увеличиваем ширину клиента if (this.scrollWidth > this.clientWidth) this.style.width = this.scrollWidth + 'px'; // Если ширина больше максимально допустимой → даем словам "ломаться" и фиксируем ширину if (this.clientWidth >= maxWidth) { this.style.width = maxWidth; this.style.whiteSpace = 'pre-wrap'; } // Если высота больше максимальной → нафиг ничЁ не надо if (this.clientHeight > maxHeight) return; // Если появляется скролл и его высота клиентской → увеличиваем высоту клиента if (this.scrollHeight > this.clientHeight) this.style.height = this.scrollHeight + 'px'; }) .demo { white-space: nowrap; overflow: hidden; }

sql вывести название категорий и посчитать количество товаров в данной категории

#mysql #sql


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



В базе данных имеются 2 таблицы 




+Product 
|_id
|_name
|_category_id
|_article





+Category
|_id
|_category_id
|_name




Посчитать количество товаров - просто.

SELECT category_id as category, count(*) AS cnt
FROM product 
GROUP BY category_id 


В результате мы получим таблицу вида:



category: 1 2 3 4 5 ... в общем номера категорий
cnt: ... количества товаров в категориях

Как мне сделать пересчет товаров и сопоставить колонку "category_id" таблицы product
с колонкой "name" таблицы Category(названия категорий) в одном запроса?

Пробовал так:

SELECT category_id as category, count(*) AS cnt
FROM product 
INNER JOIN category on product.category_id = category.category_id
GROUP BY category_id


Пробовал так:

SELECT fid AS category, COUNT(*) AS cnt, cname FROM
    (SELECT product.category_id AS fid, category.name AS cname, category.id AS cid
FROM category
    LEFT JOIN category on product.category_id = category.category_id) newtable
GROUP BY cid, cname


В общем с SQL я не силен, буду рад любой помощи. 



Ответ

SELECT category.name as category, count(*) AS cnt
FROM product 
INNER JOIN category on product.category_id = category.category_id
GROUP BY category.category_id

    


Ответы

Ответ 1



Вот так должно все нормально работать: SELECT c.name AS category, count(*) AS cnt FROM product AS p INNER JOIN category c ON p.category_id = c.category_id GROUP BY p.category_id Мой результат: "Category 01" => 2 "Category 02" => 3 "Category 03" => 4

Какая спецификация ECMAScript актуальна на данный момент?

#javascript


В тесте попался такой вопрос. Ответил 5.1 - исходил из того, что все браузеры её
используют с фичами 6.1. Насколько мне известно, чтобы писать на 6.1 нужно использовать
всякие бэйбелы и им подобные. Так и не понял, правильно ли я ответил или нет. Кто-нибудь
может подсказать, какая же версия всё-таки актуальна на данный момент? Или этот вопрос
изначально некорректен - обе версии актуальны?
    


Ответы

Ответ 1



Текущая законченная спецификация ECMA-262 7ᵗʰ Edition / June 2016 ECMAScript® 2016 Language Specification Черновик спецификации можно увидеть на гитхабе: https://tc39.github.io/ecma262/ Отсюда следует вопрос: что считать актуальной версией? Ответов на этот вопрос может быть несколько: Версия спецификации, обсуждение по которой завершено Самая последняя доступная версия Наиболее поддерживаемая браузерами Если судить по поддерживаемости браузерами, то даже шестая версия стандарта полностью не поддерживается нигде. В основном за счет части посвященной модулям и оптимизации хвостовой рекурсии. С другой стороны, если проверить поддерживаемость, то ES6 поддерживается основными браузерами на уровне 95%+ реализации. ES 2016 здесь немного хуже ситуация, реализация на уровне 70% Трудность разделения заключается так же в том, что браузеры не обязаны реализовать полностью одну версию стандарта, чтобы приступить к реализации следующей. Из-за этого получается, что все версии спецификаций могут быть реализованы не полностью и код работающий в одном браузере может не работать в другом. Исходя из этого можно предположить, что актуальная версия - 5, либо шестая версия спецификации, как наиболее поддерживаемая на данный момент (март 2017).

Ссылка на первого родителя SCSS

#css #scss


В SCCS есть  ссылка на родителя

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

SCSS

.checkbox {
    input[type="checkbox"] {
        display: none;
    }

    .checkbox-label {
        display: inline-block;
        vertical-align: middle;
        font-size: 12px;

        &:before {
            content: "";
            display: inline-block;
            vertical-align: middle;
            width: 12px;
            height: 12px;
            border: 1px solid #CCC;
            margin-right: 5px;
        }

        input[type="checkbox"]:checked + & {

            &:before {
                background-color: #0066cc;
            }
        }
    }
}


На выходе получается CSS

 .checkbox input[type="checkbox"] {
  display: none;
 }

 .checkbox .checkbox-label {
      display: inline-block;
      vertical-align: middle;
      font-size: 12px;
 }

 .checkbox .checkbox-label:before {
        content: "";
        display: inline-block;
        vertical-align: middle;
        width: 12px;
        height: 12px;
        border: 1px solid #CCC;
        margin-right: 5px;
 }

 input[type="checkbox"]:checked + .checkbox .checkbox-label:before {
        background-color: #0066cc;
 }


Почему не применятся нужный стиль или как сделать &  как ссылка на первого ближайшего
родителя?

но стоит сделать строчку 

input[type="checkbox"]:checked + .checkbox-label:before {
        background-color: #0066cc;
 }


и стиль начинает работать

пример JSFIDDLE 
    


Ответы

Ответ 1



А может всё-таки немного БЭМа? .checkbox { &__input { display: none; } /* формируем БЭМ-элементы при помощи & получаем .checkbox__input */ &__label { display: inline-block; vertical-align: middle; font-size: 12px; /* получаем .checkbox__label и т. д. */ &:before { content: ""; display: inline-block; vertical-align: middle; width: 12px; height: 12px; border: 1px solid #CCC; margin-right: 5px; .checkbox__input:checked + & { background-color: #0066cc; } } } } Пример на кодпене.

Ответ 2



Или вот есть рабочий метод, но делать так я не рекомендую никому. .checkbox { input[type="checkbox"] { display: none; } .checkbox-label { display: inline-block; vertical-align: middle; font-size: 12px; &:before { content: ''; position: relative; display: inline-block; vertical-align: middle; width: 12px; height: 12px; border: 1px solid #CCC; margin-right: 5px; $a: str-insert(#{&}, " +", 10); /* добавляем в селектор & ' +' и записываем это в переменную $a. получаем селектор .checkbox + .checkbox-label:before */ $b: selector-replace(#{$a}, '.checkbox', 'input[type=checkbox]:checked'); /* заменяем при помощи функции selector-replace ".checkbox" на "input[type=checkbox]:checked" получаем селектор input[type=checkbox]:checked + .checkbox-label:before */ @at-root #{$b}:before { background-color: #0066cc; } /* чтобы избежать наследования селекторов используем @at-root и помещаем туда наш получившийся селектор */ } } } Пример на кодпене.

Как узнать сколько денег на счете сим карты в gsm модеме, Arduino?

#arduino


Скажите, пожалуйста, как в arduino вы можете узнать, сколько денег на SIM-карте в
gsm модеме. Я знаю команду AT ("AT+CUSD=1,\"#100#\""), но я не знаю, как записать ответ
на переменную. Помогите сделать это.
    


Ответы

Ответ 1



вопрос был решён довольно давно.. но вдруг кому-то пригодится char inputGsmFullArr[200] = {0}; //массив для хранения всей смс short int indxGsm = 0; // счетчик символов для буфера String inputGsmFullStr = ""; //входящая строка с gsm модема - полная bool flagGsmActive = false; char ch = NULL; void loop() { while (gprsSerial.available()) { delay(1); flagGsmActive = true; byte c = gprsSerial.read(); inputGsmFullArr[indxGsm++] = c; logger.LogPrintBytes(c); } if (!gprsSerial.available() && flagGsmActive) { for (int i = 0; i < indxGsm; i++) { inputGsmFullStr += inputGsmFullArr[i]; } ReadGsmStr(inputGsmFullStr); ClearBufferArray(inputGsmFullArr, indxGsm); indxGsm = 0; flagGsmActive = false; Serial.flush(); gprsSerial.flush(); } } void ClearBufferArray(char *array, short int sizeBuf) // function to clear buffer array { for (byte i = 0; i < sizeBuf; i++) { array[i] = NULL; } } //Обработка смс приемника-передатчика //---------------------------------- boolean isStringMessage = false; //Флаг, что данные с GSM содержат текстовое сообщение String lineFullStr = ""; // Входная строка построчно из inputGsmFullStr String currNumTmp = ""; //---------------------------------- //--------------------------------------------------------------------------------------------------// void ReadGsmStr(String fullGmsStr) { //Очистили подстроку главной строки lineFullStr = ""; //Читаем посимвольно нашу полную СМС и выдергиваем оттуда подстроки //А вид она имеет следующий \r\n +CMT: "+79999999999","NAME","16/01/28,00:36:38+24" \r\n // 1234567890 \n // 1234567890 \r\n for (int i = 0; i < fullGmsStr.length(); i++) { //Если находим символ возврата каретки if (fullGmsStr.charAt(i) == '\r') { // если это продолжение полной смс - само тело без заголовка - 1234567890 \n - то обрабатываем то что внутри (команды) if (isStringMessage) { lineFullStr.toUpperCase(); CheckGsmSubString(lineFullStr); isStringMessage = false; } else { CheckGsmSubString(lineFullStr); } lineFullStr = ""; } else if ('\n' != fullGmsStr.charAt(i)) { lineFullStr += fullGmsStr.charAt(i); } else if ('\n' == fullGmsStr.charAt(i)) { lineFullStr += '\n'; } } inputGsmFullStr = ""; //Очищаем то что пришло с GSM } //--------------------------------------------------------------------------------------------------// void CheckGsmSubString(String gsmSubStr) { // если это текстовое сообщение if (StringContains(gsmSubStr, "+CMT")) { //Парсим смс } // если это звонок else if (StringContains(gsmSubStr, "+CLIP")) { //Парсим звонок } // этот блок отлавливает ответ на запрос баланса и отправляет его смской else if (StringContains(gsmSubStr, "+CUSD")) { IsRequestBalanceFromGsm(gsmSubStr); } //---------------------КОМАНДЫ---------------------------- // делаем запрос баланса (мтс), ответ ловится +CUSD else if (StringContains(gsmSubStr, "BAL")) { gprsSerial.println("ATD#100#"); } } //--------------------------------------------------------------------------------------------------// // запрос баланса и отправляет его смской +CUSD void IsRequestBalanceFromGsm(String str) { str = str.substring(str.indexOf("Balance"), str.indexOf("r")); delay(1500); str += " is your balance of number " + currentNumber; SendSms("ТУТ НОМЕР НА КОТОРЫЙ ОТПРАВЛЯТЬ ОТВЕТ", str); } //--------------------------------------------------------------------------------------------------// const char q = (char)34; // символ " const char r = (char)13; // символ возврата каретки (Enter) const char z = (char)26; // передача ^Z // Функция отправки смс void SendSms(String number, String text) { logger.LogPrintlnStr("SEND SMS FUNC RETURN: "); logger.LogPrintlnStr("NUMBER: " + number + "\nTEXT: " + text); gprsSerial.println("AT+CMGD=4"); //удалить все сообщения на сим карте delay(1500); gprsSerial.print("AT+CMGS="); // send the SMS the number gprsSerial.print(q); // передача в порт символа " gprsSerial.print(number); // передача номера телефона gprsSerial.print(q); // передача в порт символа " gprsSerial.print(r); delay(1500); gprsSerial.println(text); // передача текста сообщения delay(500); gprsSerial.print(z); // передача ^Z gprsSerial.print(r); // передача Enter }

Ограничение на перемещение мыши

#javascript


Задача в том, что я не могу сделать так, чтобы мышь не доходила до блока. Нужно сделать
так, чтобы, например, при расстоянии 10px мыши от блока блок переместился.



var div = document.createElement('div');
div.className = "myDiv";
with(div.style) {
  width = '100px';
  height = '100px';
  backgroundColor = 'red';
}
document.body.appendChild(div);
div.addEventListener("mousemove", draw);
div.addEventListener('mouseover', count);


function draw() {
  this.style.left = Math.random() * document.body.clientWidth + 'px';
  this.style.top = Math.random() * document.body.clientHeight + 'px';
  mouseMove(event)
}

var x = 0;

function count() {
  this.innerHTML = x += 1;
}
* {
  margin: 0;
  padding: 0;
  position: relative;
}




  
  Title









    


Ответы

Ответ 1



Пусть тогда документ сам следит за мышами - и как только они подберутся поближе - убирает всё ценное куда подальше. var cheese = document.querySelector('.cheese'); // За мышью следит сам документ: document.addEventListener("mousemove", mm); document.addEventListener('mouseover', mo); var border = 10; function mm(e) { if (e.clientX > cheese.offsetLeft - border && e.clientX < cheese.offsetLeft + cheese.offsetWidth + border && e.clientY > cheese.offsetTop - border && e.clientY < cheese.offsetTop + cheese.offsetHeight + border ) { // если мышь слишком близко - убираем сыр! cheese.style.left = Math.random()* (window.innerWidth - 30) + 'px'; cheese.style.top = Math.random() * (window.innerHeight - 30) + 'px'; } } function mo(e){ if (e.target === cheese) cheese.innerText = +(cheese.innerText || 0)+1; } * { margin: 0; padding: 0; position: relative; } .cheese { display: inline-block; width: 30px; height: 30px; background-color: yellow; }


куча mmap в простейшем коде дампа stacktrace

#cpp #linux


здравствуйте, вот решил прогнать через strace бинарник хелловорлда:

#include

int main(int argc, char *argv[]) {
    std::cout<<"hello world";
}


с -О2 генерируется в это:

.LC0:
    .string "hello world\n"

main:
    subq    $8, %rsp
    movl    $.LC0, %esi
    movl    std::cout, %edi
    call    std::basic_ostream >& std::operator<< 
>(std::basic_ostream >&, char const*)
    xorl    %eax, %eax
    addq    $8, %rsp
    ret

_GLOBAL__sub_I_main:
    subq    $8, %rsp
    movl    std::__ioinit, %edi
    call    std::ios_base::Init::Init()
    movl    $__dso_handle, %edx
    movl    std::__ioinit, %esi
    movl    std::ios_base::Init::~Init(), %edi
    addq    $8, %rsp
    jmp     __cxa_atexit


и вот теперь совершенно не ясно откуда такой выхлоп у strace:

execve("./exceptions", ["./exceptions"], [/* 39 vars */]) = 0
brk(NULL)                               = 0x1d4d000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a31000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=150385, ...}) = 0
mmap(NULL, 150385, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff6f4a0c000
close(3)                                = 0
open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6", 
O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\t\t\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2051952, ...}) = 0
mmap(NULL, 4161184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4419000
mprotect(0x7ff6f45fe000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f47fd000, 69632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x1e4000) = 0x7ff6f47fd000
mmap(0x7ff6f480e000, 11936, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x7ff6f480e000
close(3)                                = 0
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260V\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1062976, ...}) = 0
mmap(NULL, 3158248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4115000
mprotect(0x7ff6f4218000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f4417000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x102000) = 0x7ff6f4417000
close(3)                                = 0
open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220*\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=92312, ...}) = 0
mmap(NULL, 2188320, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f3efe000
mprotect(0x7ff6f3f14000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f4113000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x15000) = 0x7ff6f4113000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\3\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1656280, ...}) = 0
mmap(NULL, 3762456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f3b67000
mprotect(0x7ff6f3cf4000, 2097152, PROT_NONE) = 0
mmap(0x7ff6f3ef4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x18d000) = 0x7ff6f3ef4000
mmap(0x7ff6f3efa000, 14616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x7ff6f3efa000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a0a000
arch_prctl(ARCH_SET_FS, 0x7ff6f4a0b5c0) = 0
mprotect(0x7ff6f3ef4000, 16384, PROT_READ) = 0
mprotect(0x7ff6f4113000, 4096, PROT_READ) = 0
mprotect(0x7ff6f4417000, 4096, PROT_READ) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a08000
mprotect(0x7ff6f47fd000, 53248, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7ff6f4a33000, 4096, PROT_READ) = 0
munmap(0x7ff6f4a0c000, 150385)          = 0
brk(NULL)                               = 0x1d4d000
brk(0x1d7f000)                          = 0x1d7f000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "hello world", 11hello world)             = 11
exit_group(0)                           = ?
+++ exited with 0 +++


поясните, пожалуйста, откуда такая куча mmap?
    


Ответы

Ответ 1



strace — это утилита, отслеживающая системные вызовы, которые представляют собой механизм трансляции, обеспечивающий интерфейс между процессом и операционной системой (ядром). Эти вызовы могут быть перехвачены и прочитаны. Это позволяет лучше понять, что процесс пытается сделать в заданное время. Перехватывая эти вызовы, мы можем добиться лучшего понимания поведения процессов, особенно если что-то идет не так. Функциональность операционной системы, позволяющая отслеживать системные вызовы, называется ptrace. Про неё можно почитать Wiki, Ман и хабр. Теперь прокоментирую некоторые строчки дампа execve("./exceptions", ["./exceptions"], [/* 39 vars */]) = 0 brk(NULL) = 0x1d4d000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a31000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 открытие файла, возврат дескриптора №3. fstat(3, {st_mode=S_IFREG|0644, st_size=150385, ...}) = 0 посмотреть размер mmap(NULL, 150385, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff6f4a0c000 Отобразить весь модуль кеша в гдеугодно памяти -> Размещён по адресу 7ff6f4a0c000 close(3) Закрыть дескриптор 3 open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3 открыть модуль, выдан снова уже свободный дескриптор №3. read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\t\t\0\0\0\0\0"..., 832) = 832 читаем заголовок файла (elf), дальше идёт расчёт секций fstat(3, {st_mode=S_IFREG|0755, st_size=2051952, ...}) = 0 Получить размер файла mmap(NULL, 4161184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4419000 Помещаем одну из readonly секций в память mprotect(0x7ff6f45fe000, 2093056, PROT_NONE) = 0 резервируем секцию (? незнаю зачем, скорее всего для помещения туда данных c помощью mmap) mmap(0x7ff6f47fd000, 69632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e4000) = 0x7ff6f47fd000 эту секцию на полный доступ mmap(0x7ff6f480e000, 11936, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ff6f480e000 и эту секцию на полный доступ close(3) закрыли файл ... brk(0x1d7f000) = 0x1d7f000 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 это похоже подготовка консоли к работе. write(1, "hello world", 11hello world) собственно ваш вывод в консоль exit_group(0) ну и выход с программы. О дескрипторах можно сказать что 1=STDOUT. 3=файл или свободный после close. 2 - не могу сказать что там. И последнее, mmap скорее всего делает поправку на таблицу размещения. Механизм линкования библиотек у линукса немного необычный, описывать его - отдельная статья.

Для каких целей используется NodeJs?

#веб_программирование #nodejs #aspnet #aspnet_mvc


Если я правильно понял Wiki, то он дает возможность использовать JavaScript на стороне
сервера.
Однако, в виду своего малого опыта я не могу представить задачи, которые можно было
решать только лишь его средствами.
Подскажите, под какие задачи обычно используется NodeJs или это какая-то узконаправленная
штука?
Используют ли его в ASP.NET MVC?
    


Ответы

Ответ 1



Node.js используют под совершенно разные задачи. Например: как backend для различных сетевых сервисов (не только веб): Express; Koa; Meteor; как платформу для IoT (Internet of Things): Cylon; Robot.js; как платформу для написания настольных приложений: Atom; как платформу для написания системных инструментов, в том числе: менеджеров пакетов: npm, bower, jspm; систем сборки проекта: gulp, grunt; систем упаковки ресурсов: browserify, webpack; PostCSS; babel (транслятора из современного Javascript в более старые версии); tsc (компилятора Typescript); В ASP.NET MVC его можно использовать, например для работы с CSS (PostCSS) или для перекомпиляции JS (Babel). Более того, старая версия node.js поставляется вместе с Visual Studio 2015 - и такие вещи как tsc в некоторых шаблонах проектов настроены из коробки.

Ответ 2



Цитата из книги Брауна "Web разработка с использованием Node.js и Express": "Случалось ли вам заходить на сайт, видеть строку запроса, заканчивающуюся ***.asp, и думать - как же этот сайт устарел!" Вы бы лучше спросили, чего Node.js не может. Javascript - наверное, самый ушлый язык: ворует все лучшие идеи из всех языков и платформ (что особенно трогательно - много из Lisp, самый трогательный си-образный наследник великого Lisp). Короче, это язык (и платформа) для людей, больше всего ценящих свободу.

Ответ 3



Использую его в Back-End. Если про конкретику, то он отлично подходит для IM-сервера, сервера очереди сообщений, а также любых вещей, связанных с Back-End обработкой данных.

Ответ 4



Например, я делал реалтайм игру под Вконтакте. Node.js использовал для front-end(балансировщик между серверами) и back-end. Node.js способен даже заменить ungix для отдачи статики, хотя это полемика на форумах развела не слабые рассуждения.

Get-запрос. Ошибка "Сервер нарушил протокол. Section=ResponseStatusLine

#c_sharp #get


Доброе время суток!
При вызове Get метода, catch(Exception ex) выводит ошибку "Сервер нарушил протокол.
Section=ResponseStatusLine.

код на клиенте Метод get-запроса:

  public String URL = "http://192.168.16.254:8080/blinkSs";
    string r = "";
    private string GET(string sUrl, string Data)
    {

        System.Net.WebRequest req = System.Net.WebRequest.Create(sUrl + "?" + Data);
        System.Net.WebResponse resp = req.GetResponse();
        System.IO.Stream stream = resp.GetResponseStream();
        System.IO.StreamReader sr = new System.IO.StreamReader(stream);
        string Out = sr.ReadToEnd();
        sr.Close();
        return Out;

    }


Вызываю метод GET вот так:

if (e.KeyCode == Keys.Up)
            {
                try
                {
                    r = "oske";
                    String a=GET(URL, r);
                    MessageBox.Show(a);
                }
                catch(Exception ex) {
                    MessageBox.Show("error" + " " + ex.Message);
                }
            }


код на сервере:

void setup() {     
  Serial.begin(115200);  
  pinMode(13, OUTPUT); //Rele 1
  //pinMode(12, OUTPUT);  //Rele 2
}
int f = 0;
String com_get = "";//
void loop() {
  boolean has_request = false;
  String in = "";
  if (Serial.available()) {
    in = "";
    while (true) {  // should add time out here
      while (Serial.available() == false) {}
      in += (char)(Serial.read());//тут хттп запрос, урл адресс
      if (in.endsWith("\r\n\r\n")) {//если первая строка (string) завершается символом,
содержащимся в строке string2
        has_request = true;  break;
      }
    }   
  }
  if (has_request) {
    int i1 = in.indexOf("GET /blinkSs?"), i2;//13 символов
    if (i1 != -1) {
      i2 = in.indexOf(" ", i1+13);//кол. символов с 13ого
      f = in.substring(i1+13, i2).toInt();//запрос
      com_get=in.substring(i1+13, i2);
    }      


    //Serial.println("HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: close");
     //String sr = "";
     //Serial.println(sr);
    // Serial.println("");
     //Serial.println("");
     //Serial.println("");
     //Serial.println("");
    if (com_get=="oske") {f=1; Serial.println("Comando 1. oske"); } //↑
    if (com_get=="aska") {f=2; Serial.println("Comando 2. aska"); }//↓
    if (com_get=="kren_unga") {f=3; Serial.println("Comando 3. kren_unga"); }// /
    if (com_get=="kren_sulga") {f=1; Serial.println("Comando 1. kren_sulga"); }// \

   //Serial.println("");
   //Serial.println("\n");
    has_request = false;
  }
switch (f){
  case 1:
   digitalWrite(13, HIGH);
   break;
  case 2:
   digitalWrite(13, LOW);
   break;  
   f=0;
   Serial.end();

}  

}

    


Ответы

Ответ 1



В файл app.config добавьте Задание этого свойства игнорирует ошибки проверки, возникающие при анализе HTTP.

Ответ 2



Очевидно же, что ты на сервере код состояния Status-Line не отправляешь. Изучи RFC https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html Response = Status-Line ; Section 6.1 *(( general-header ; Section 4.5 | response-header ; Section 6.2 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 7.

Возведение последовательности чисел в степень

#c_sharp


Допустим, есть последовательность чисел [0,1,2,3,4..n]. Как её можно задать, после
чего каждое число возвести в определенную степень (например, во вторую)?
Т.е. на экран должен выводиться ответ вида [0,1,4,9...].

Я так понимаю, это работа с массивами?
    


Ответы

Ответ 1



На экран результат можно выводить и без использования массива. А именно перебирать последовательно идущие числа в цикле, возводить их в нужную степень и выводить результат сразу на экран. Для возведения в степень используется метод Math.Pow. int n = 10; int power = 2; for (int i = 0; i < n; i++) { Console.Write(Math.Pow(i, power) + " "); } Если результирующие числа нужные ещё для чего-то, то действительно имеет смысл сохранить их в массиве: int n = 10; int power = 2; double[] result = new double[n]; for (int i = 0; i < n; i++) { result[i] = Math.Pow(i, power); } Console.WriteLine(string.Join(" ", result));

Ответ 2



//Задаёте последовательность в виде массива целочисленных переменных, инициализируя массив при объявлении var numberArray = new int[] { 0,1,2,3,4,5,6 }; //т.к. массив реализует IEnumerable, можно воспользоваться циклом foreach foreach (var number in numberArray) { //Выводим в консоль значение каждой переменной из последовательности, предворительно возводя её во вторую степень при помощи Math.Pow() Console.Write(Math.Pow(number, 2) + " "); }

Смысл CSRF Token`а

#веб_программирование #token #csrf


Доброго времени суток! 

Изучаю csrf и не могу понять одну вещь, помогите пожалуйста разобраться.
На сайте learn.javascript есть статья по этому поводу. Там сказано:


  Типичный способ защиты сайтов – это «секретный ключ» (secret),
  специальное значение, которое генерируется случайным образом и
  сохраняется в сессии посетителя. Его знает только сервер, посетителю
  мы его даже не будем показывать.
  
  Затем на основе ключа генерируется «токен» (token). Токен делается
  так, чтобы с одной стороны он был отличен от ключа, в частности, может
  быть много токенов для одного ключа, с другой – чтобы было легко
  проверить по токену, сгенерирован ли он на основе данного ключа или
  нет.
  
  Для каждого токена нужно дополнительное случайное значение, которое
  называют «соль» salt.
  
  Формула вычисления токена:
  
  token = salt + ":" + MD5(salt + ":" + secret) Например:
  
  В сессии хранится secret="abcdef", это значение создаётся один раз.
  Для нового токена сгенерируем salt, например пусть salt="1234". token
  = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401".
Это значение – с одной
  стороны, случайное, с другой – имея такой token, мы можем взять его
  первую часть 1234 в качестве salt и, зная secret, проверить по
  формуле, верно ли он вычислен.
  
  Не зная secret, невозможно сгенерировать token, который сервер
  воспримет как правильный.
  
  Далее, токен добавляется в качестве скрытого поля к каждой форме,
  генерируемой на сервере.При её отправке сервер проверит поле csrf,
  удостоверится в правильности токена, и лишь после этого отошлёт
  сообщение.
  
  «Злая страница» при всём желании не сможет сгенерировать подобную
  форму, так как не владеет secret, и токен будет неверным.


Мне непонятно вот что:


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


Сайт разрешает кросс-доменные запросы от всех Origin: *
либо
Злоумышленник мог ранее уже встроить форму на тот же сайт через XSS, чтобы оставаться
в том же домене, так как во всех остальных случаях у нас есть CORS, зачем нам CSRF?

Не понял, почему формула токена именно такая:

token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401"


Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль
1234 становится явно видна в токене!
Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет
токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем,
что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если
можно?)


Спасибо заранее за помощь!
Отличие от данного вопроса в том, что там так и не понятно, зачем нужен CSRF если
есть CORS
    


Ответы

Ответ 1



secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то? Только если у него есть доступ к компьютеру пользователя. Но тогда ему вообще CSRF не нужен, т. к. есть куда более простые способы отправить запрос самому. Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса? Только в случае MITM. При CSRF у хакера нет доступа к серверу, клиенту или каналу связи. я имею в виду разве он не может получить форму просто еще раз скриптом и этот токен потом отправить в своем запросе? Не может - тут сработает CORS. Если запрос get, то сервер его получит, но если он не пошлёт разрешающие заголовки, то запрашивающему скрипту браузер ответ не отдаст. А на POST вообще будет OPTIONS-запрос сначала. А если послать запрос не из браузера, а с сервера, то не будет авторизации пользователя и токен он опять же не получит. Я так понимаю смысл всей этой ерунды есть только тогда, когда либо Сайт разрешает кросс-доменные запросы от всех Origin: * либо ... Нет. Браузер позволит отправит форму, вот:
Не понял, почему формула токена именно такая: Форма может быть разной. Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене! Если соли нет, то ключ одного клиента подойдёт другому и хакер сможет использовать свой, поэтому нужна соль. Хм.. А вообще, что-то я задумался, есть тут сомнения... Разобрался: даже если хакер встроит свой валидный токен в форму, он не совпадёт с токеном в куках, поэтому форма будет отвергнута как поддельная. он не совпадет, потому что хакеру неизвестен id сессии, на основе котороой генерируется токен? Я имел в виду, что у хакера может быть свой токен, который корректен для него. Но этот токен не совпадёт с тем токеном, который лежит у другого пользователя в куках. А из чужих кук он его достать не может. Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?) Сайт не может залезть в чужие куки, поэтому подсмотреть нельзя.

Ответ 2



Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене! А ее и не нужно прятать. Она не для прямой секретности, а для двух других целей: Если результирующий хэш берется от пароля в чистом виде, то этот пароль можно подгадать по словарю. Случайная соль гарантирует, что по словарю этот секрет подобрать не удастся, а сгенерированный для одной соли словарь не подойдет для другой. В этом случае, конечно, предполагается что секрет у каждого клиента свой, иначе в случае подбора конкретного хэша есть риск, что там совпадет не только хэш, но и исходные данные, и тогда секрет будет известен атакующему Ресурсы, затрачиваемые хэш-функцией на создание хэша зависят от длины входной последовательности. Искусственно увеличивая входную последовательность, защищающийся повышает стоимость подбора совпадений для атакующего, потому что из-за маловероятности подбора коллизии случайным образом атакующий будет пробовать подобрать хэш, используя соль.

Адаптация рулетки под ширину

#javascript #html #css




function doubleRoll(winner) {
  var rollPositions = {
    0: -10178,
    1: -10240,
    2: -10366,
    3: -10492,
    4: -10618,
    5: -10744,
    6: -10870,
    7: -9676,
    8: -9802,
    9: -9928,
    10: -10054,
    11: -10304,
    12: -10430,
    13: -10556,
    14: -10682,
    15: -10808,
    16: -10934,
    17: -9738,
    18: -9864,
    19: -9990,
    20: -10116
  }
  var roll = rollPositions[winner];
  $('.roulette_table').css('transition', '10s cubic-bezier(.25,0,.5,1)');
  $(".roulette_table").css({
    "margin-left": "" + roll + "px",
  });
  setTimeout(function() {
    $('.roulette_table').css('transition', 'none');
    $(".roulette_table").css({
      "margin-left": "" + (roll + 9238.5) + "px",
    });
  }, 10500);
}
#round_draw_pointer_mid {
    position: absolute;
    top: 0;
    margin: auto;
    width: 5px;
    height: 100%;
    background: #000;
}
.roulette_option {
    text-align: center;
    color: #fff;
    display: inline-block;
    width: 60px;
    height: 80px;
        margin-left: -1.6px;
    line-height: 25px;
    vertical-align: middle;
    border-top: 2px solid rgba(0,0,0,.5);
}
   
.roulette_table {
    width: 15000px;
    height: 150px;
    overflow-y: hidden;
    position: absolute;
}
#round_draw_pointer {
    height: 100%;
    width: 2px;
    position: absolute;
    left: 0;
    right: 0;
    margin: auto;
    z-index: 99;
}
.roulette_option span {
    font-size: 18px;
    font-weight: bold;
    background: rgba(255,255,255,.08);
    display: block;
}
.roulette_table_holder {
    width: 100%; /* если указать 810px, будет работать как надо! */
    height: 80px;
    overflow: hidden;
    position: relative;
}

0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
0
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20



Такс, значит задача стоит следующая.. есть рулетка в ней есть 20 разных позиций. Но так получилось, что делал эту рулетку под ширину 810px, а надо чтобы она растягивалась на весь экран те width = 100% Если поменять в стилях в селекторе .roulette_table_holder указать параметр width = 100%;, то рулетка будет работать как надо, но если указано 100% (как и надо), то она не адаптивна, и выпадает совсем другое число.


Ответы

Ответ 1



В итоге переписал весь код. И сделал так: function doubleRoll(winner) { if ($(".roulette_table").length > 0) { var number = winner; if (number == 0) { numberCalc = 0; } else if (number > 10) { numberCalc = 2 * (number - 10); } else { numberCalc = 2 * (number) - 1; } var numberMargin = 60 * numberCalc; var randPos = Math.floor(Math.random() * 52) + 6 var centerMargin = -21 * 60 + 60 * 7 + $("#page_content").width() / 2; var startMargin = centerMargin - numberMargin - randPos - 5458; $(".roulette_table").css('left', startMargin + 'px').css('transition', '10s cubic-bezier(.25,0,.5,1)'); } setTimeout(function() { $('.roulette_table').css('transition', 'none'); $(".roulette_table").css({ "left": ""+ (startMargin + 5040) +"px", }); }, 10500); }

Как поменять серию c номером k повторяющихся элементов в списке c последней серией в списке?

#python #алгоритм


Пусть k = 2

Скажем, есть список:  

array = [2,2,4,5,5,7,1,6,9,9,2]


Необходимо сделать так, чтобы было: 

array = [2,2,4,9,9,7,1,6,5,5,2]

    


Ответы

Ответ 1



Алгоритм: найти позиции k-ой и последней серий, состоящих из повторяющихся элементов поменять их местами from itertools import groupby # 1. find the k-th and the last group with repeated items pos = 0 # position in the array repeated_group_count = 0 for _, group in groupby(array): n = len(list(group)) pos += n if n > 1: # found group with repeated items last_start, last_end = pos - n, pos repeated_group_count += 1 if repeated_group_count == k: k_start, k_end = last_start, last_end # 2. swap the k-th and the last group if repeated_group_count > k: array[:] = (array[:k_start] + array[last_start:last_end] + array[k_end:last_start] + array[k_start:k_end] + array[last_end:]) Это линейный по времени и памяти алгоритм. При желании можно по месту, без дополнительной памяти замену сделать (к примеру, используя аналог std::rotate()).

Ответ 2



Мне показалось, что со строками будет проще работать, да и вспомнить один трюк из регулярок захотелось: def foo(array, k): # Представим список как строку array_str = ','.join(map(str, array)) import re seq_groups = re.findall(r'((\d)(,\2)+)', array_str) if not seq_groups: print('Not found groups') # Найденные последовательности в списке seq_groups = [seq for seq, _, _ in seq_groups] print('groups:', seq_groups) # Берем все группы после индекса k - 1 и из них выбираем первую group_1 = seq_groups[k-1:][0] # Берем последнюю группу group_2 = seq_groups[-1] # Замена одной группы на другую array_str = array_str.replace(group_1, "__") array_str = array_str.replace(group_2, group_1) array_str = array_str.replace("__", group_2) # Разбиваем список, приводим все элементы к числу, возвращаем # как список return list(map(int, array_str.split(','))) Проверка: array = [2,2,4,5,5,7,1,6,9,9,9,2] k = 2 print(foo(array, k)) # [2, 2, 4, 9, 9, 9, 7, 1, 6, 5, 5, 2] k = 1 print(foo(array, k)) # [9, 9, 9, 4, 5, 5, 7, 1, 6, 2, 2, 2]

Как получить координаты найденного цвета?

#python #python_3x #opencv #numpy


Часть кода:

import numpy as np
import cv2

image = cv2.imread('example.png')
limit = np.array([255, 255, 255], dtype='uint8')

mask = cv2.inRange(image, limit, limit)
output = cv2.bitwise_and(image, image, mask=mask)

cv2.imshow('images', output)
cv2.waitKey()


Результат:



Каким образом можно получить (x, y) найденного цвета? Заранее спасибо.
    


Ответы

Ответ 1



Найти все координаты: import numpy as np y,x = np.where(mask != 0) верхняя левая точка: In [74]: print((x[0], y[0])) (146, 80) нижняя правая: In [75]: print((x[-1], y[-1])) (208, 92)

Горячие клавиши на команды

#c_sharp #wpf


В программе используется TabControl. 

На одной из вкладок пользователь может создавать новый проект. 

Нужно привязать горячие клавиши CTRL+N для команды создания проекта.

Гугл подсказывает, что горячие клавиши задаются таким образом:


    
     


Но загвоздка в том, что когда пользователь находится на вкладке настроек не нужно,
чтобы CTRL+N срабатывало.

Можно ли указать свои горячие клавиши для каждой из вкладок?
    


Ответы

Ответ 1



Конечно можно.

Как загрузить шрифт Roboto v15?

#google_fonts


Для загрузки всегда использовал данную ссылку: "https://fonts.googleapis.com/css?family=Roboto:400,900&subset=latin,cyrillic",
но уже несколько дней наблюдаю, что шрифт Roboto 16px стал более вытянутый. Смотрю
в файл css, а там фигурирует новая версия "s/roboto/v16/".

Вопрос, можно ли как-то принудительно указать, что мне нужна именно 15 версия?
    


Ответы

Ответ 1



Эта проблема уже неделю обсуждается в репозитории Roboto. https://github.com/google/roboto/issues/243 и https://github.com/google/roboto/issues/244 Говорят, что так стало "лучше", поскольку исправлена некая ошибка, которую мало кто замечал, а то, что шрифт стал выглядеть как другой шрифт - это, как говорится, "ваши проблемы" (при этом шрифт Roboto используется более чем на 10 миллионах сайтов и на многих порушил дизайн). Единственный вариант решить этот вопрос раз и навсегда - грузить нужную версию шрифта со своего хоста, не надеясь и не рассчитывая на неконтролируемые сторонние сервисы.

Как сымитировать нажатие нескольких клавиш на клавиатуре, включая специальные на Windows?

#python #windows


Установил себе модуль win32com.client
В нём можно сделать имитацию нажатия клавиш (А ля Ctrl + C):

shell = win32com.client.Dispatch('WScript.Shell')
shell.SendKeys('^a^x')


Однако в процессе появилась одна очень странная особенность: все эти имитация нажатия
запускаются в фоновом потоке. В моём случае это недопустимо. Каким образом сделать
так, чтобы вся программа ждала, пока сымитируется нажатие? Пробовал threading - получилось,
однако программа теперь вместо 0.1с. работает 3с, что недопустимо.
    


Ответы

Ответ 1



Если не принципиально использование модуля win32com.client, можно воспользоваться более удобным pywinauto (он ждёт отправки клавиш в приложение): from pywinauto.application import Application from datetime import datetime # Запускаем блокнот app = Application().start("notepad") # Можно посылать спецсимволы # app.UntitledNotepad.Edit.type_keys("^a^v") # app.UntitledNotepad.Edit.type_keys("{VK_F5}") # Вставим текущее время для проверки app.UntitledNotepad.Edit.type_keys(datetime.now().strftime("%H:%M:%S.%f")) print(datetime.now().strftime("%H:%M:%S.%f")) Документация по эмуляции клавиатурных нажатий Тестировалось на Python 3.6 со свежим pywinauto, Windows 7 64-bit

Класс std::ifstream, метод получения имени файла

#cpp #файлы


Доброго времени суток. Покопал много страницы учебников/интернета, но так и ничего
не нашёл. Иногда требуется получить имя файла, к которому привязан файловый поток.
Неужели нет ни функций\ни методов чтобы такое провернуть?\n
Заранее спасибо. Пока что спасаюсь немного костыльно:

class File :public std::ifstream 
{
    std::string name;
public:
    File():name(""), std::ifstream(){}
    File(const char* n, ios_base::openmode m = ios_base::in | ios_base::out):name(n),
std::ifstream(n, m){}
    std::string name_file()
    {
        return this->name;
    }
};

    


Ответы

Ответ 1



Пожалуй, лучшее, что вы можете сделать - самостоятельно хранить имя. Поскольку в стандарте об этом ничего не сказано - как минимум вы не можете получить имя файла переносимо. Вряд ли его какая-то реализация вообще хранит. Даже просто найти по дескриптору операционной системы имя файла - задача нетривиальная (и не уверен, что вообще везде разрешимая). Кстати, представим себе символические линки (или hard линки) - и какое имя файла теоретически нужно возвращать? А файл к тому же - еще и не всегда именно дисковый файл - например, откройте в Windows fstream с именем con - вывод пойдет на консоль. Можно отправить на принтер или еще куда. Как я понимаю, все эти соображения вкупе с тем, что вы-то знаете, что открывали - привели к тому, что ни в C, ни в C++ нет функций получения имени файла из файлового объекта/потока.

Создание временного окна (Окно уведомлений)

#c_sharp #wpf #xaml


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

AlarmWindow alarm = new AlarmWindow(alarmMessage);
alarm.Show();
//либо
AlarmWindow alarm = new AlarmWindow()
{
    DataContext = alarmMessage
};
alarm.Show();

    


Ответы

Ответ 1



Должно работать так: void TickHandler(...) { Application.Current.Dispatcher.InvokeAsync(async () => { AlarmWindow alarm = new AlarmWindow(alarmMessage); alarm.Show(); await Task.Delay(2000); alarm.Close(); }); }

Ответ 2



Добавьте в форму таймер с интервалом задаваемым через конструктор. И по событию таймера закрывайте форму изнутри. partial class AlarmWindow:Form{ public AlarmWindows(string msg, int timeToShow){ ... System.Timers.Timer closeMe = new System.Timers.Timer((double)timeToShow); closeMe.Elapsed += closeMe; closeMe.AutoReset = false; closeMe.Start(); ... } void closeMe(object sender, System.Timers.Timer e){ this.close(); }

Ответ 3



Помог следующий способ: AlarmWindow alarm = new AlarmWindow(alarmMessage); alarm.Show(); System.Threading.Thread.Sleep(2000); // (!) вешает программу на 2 секунды, alarm.Close(); //поэтому в основном потоке использовать крайне не рекомендуется Так делать не стоит!!! Вот >тут< есть более корректный ответ.

как в bat файле сделать так, чтобы после выполнения bat файл не закрывался

#bat


Как в bat файле сделать так, чтобы после выполнения bat файл не закрывался?
    


Ответы

Ответ 1



Можно помледней строкой поместить что-то из этого: pause cmd Либо запускать так: cmd /k smth.bat или даже так (если он иногда делает exit): cmd /k cmd /c smth.bat

отличия использования позиционирования и margin

#css #position #margin


С того момента, как я узнал о позиционировании в css, для меня является загадкой
разница между отступами с помощью margin(1) и top\right\bottom\left(2).

В моём представлении, эти два атрибута делают одно и то же, и единственное их различие,
которое смог найти - это то, что (1) относится к box-model, когда (2) - нет.

Так же знаю о применении (2) для "относительности сторон", т.е. вещи вроде:

top: 0;
left: 0;


И тогда он будет "прибит" к левому верхнему краю.

Вопрос состоит в том, когда какой инструмент использовать?
    


Ответы

Ответ 1



Чтобы понять разницу, вам нужно попробовать поставить больше одного элемента: .m { margin: 10px; } .r { top: 10px; left: 10px; right: 10px; bottom: 10px; position: relative; } div { height: 30px; width: 30px; border: 1px solid #999; display: inline-block; } body{ font-size: 0;} span{ font-size:15px;}
без отсупов:

margin:

top/left:

Вы видите в примере, что margin создает настоящий отступ вокруг каждого элемента, сдвигая соседние. top/left же просто сдвигает элементы вниз и влево, никак не влияя на верстку. Теоретически, top/left больше похож на transform: translate, с отличием в аппаратном ускорении и относительных еденицах

Ответ 2



Я всегда рисовал себе правила - на листике: margin (внешний отступ) | padding (внутренний отступ): ↑ → ↓ ←; Хорошо запоминается. Есть случаи, когда margin не сможет исправить ситуацию отступа от рамки и текст внутри рамки, будет казаться прилипшим, на помощь придет padding, который сделает внутренний отступ от рамки элемента.

KDE: Автоматическая замена последовательности символов “---” (три дефиса) на “—” (тире)

#kde


Как сделать в KDE, чтобы при вводе трёх дефисов ("---") они автоматически (сразу
или после нажатия пробела, когда именно не столь важно) заменялись на тире ("—")?
    


Ответы

Ответ 1



Как советуют в комментариях, желаемого поведения можно добиться, назначив клавишу Compose. В KDE соответствующая настройка находится в разделе Устройства ввода/Дополнительно/Положение клавишы Compose. Назначив эту клавишу можно будет вводить тире через комбинацию Compose + три дефиса. Вводить тире становится особенно удобно, если учитывать, что при наборе трёх дефисов необязательно держать Compose нажатой. То есть так тоже работает: Нажимаем Compose Отпускаем Compose Набираем три дефиса

Вывод дерева mysql

#mysql #sql #дерево


Есть таблица elements следующей структуры Adjacency List Model:

id parent index


Где index - это порядок элемента.
Нужно одним запросом сформировать путь, получающийся при обходе в глубину.
То есть если у нас такой вид:

1 0 1
2 0 2
3 1 1
4 1 2
5 2 1
6 0 3


То выведется
1 3 4 2 5 6

Нужно на чистом mysql без использования php и тд.
Заранее спасибо

P.S. Менять в структуре, к сожалению, ничего нельзя

Заранее спасибо
    


Ответы

Ответ 1



В MySQL нет штатных средств для работы с рекурсивными запросами. Но как известно, если очень хочется, то можно (хотя выглядит это жутковато и оптимизации по скорости это не поддается): select id,path from ( select @path:=if(@id!=id,`index`, coalesce( (select concat(`index`,'/',@path) from Tree1 where id=@pid) ,@path) ) path, @pid:=if(@id!=id,parent, (select parent from Tree1 N where id=@pid) ), @id:=id id, N from Tree1 T, (select @n:=@n+1 N from Tree1,(select @n:=0) N limit 3) Seq, (select @id:=0,@path:='') X order by id, N ) X where N=3 order by path Так как ни рекурсии ни циклов в обычном смысле слов нет, то запрос эмулирует рекурсию с помощью эмуляции цикла. В качестве цикла используется склейка с любой таблицей, в которой записей не менее, чем максимально возможный уровень иерархии в дереве. В данном примере используется выборка из той же самой таблицы, явно ограниченная limit 3 (если вложенность дерева больше - число надо соответственно увеличить). Собственно данные из этой таблицы не берутся, а создаются порядковые номера (N). После этой склейки у нас в выборке появляется по 3 записи с одним и тем же id. На каждой из них, с помощью переменных, мы получаем id очередной родительской ветки, углубляясь по дереву (так как переменные помнят значения, сформированные в предыдущей строке). Самое главное, что мы тут формируем это путь к данной записи в виде индексов сортировки (если index может быть более 9 то для правильной сортировки надо выравнивать его в пути до одинаковой длины с помощью lpad()) В какой то момент записи родителей заканчиваются, мы дошли до корня дерева, тогда подзапрос индекса родителя возвращает NULL и при этом с помощью coalesce мы сохраняем ранее сформированный путь. Таким образом в последней записи нашего "цикла" у нас гарантированно будет полный путь до данного листа дерева. Нам остается только убрать из выборки рабочие строки цикла с частично сформированными путями, т.е. выбрать только последние строки (where N=3) и отсортировать по пути индексов.

Ответ 2



Чтобы вывести полный путь в одном запросе нужно использовать Nested Set Model. (Полная информация по ссылке) Для построения пути можно использовать хранимую функцию. При процедурном языке мы можем начать в нижней части дерева и перебирать вверх, чтобы вернуть полное дерево или единственный путь. https://web.archive.org/web/20110606032941/http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

Как использовать геотаргетинг яндекса без карты?

#javascript #yandex_maps_api #геолокация #геокодирование


Определяю местоположение пользователя так:




    
        
    
    
        
        
        
Как в данном примере не создавать карту в DOM? Если убираю div(точнее id="YMapsID"), то возникает ошибка Uncaught TypeError: Cannot read property 'push' of undefined Если убираю - переменную map - тоже ошибка. Установить св-во hidden - тоже не хотелось бы.


Ответы

Ответ 1



Вот и вариант когда мы только получаем данные геопозиции пользователя, и не инициализируем карту. Делаем только инициализацию YMaps и после этого он уже получает данные геопозиции пользователя, В примере я после этого просто вывел эти данные в console․


Set, Multiset, Map, Multimap

#cpp


В чем разница между ними и примеры, если можно.
    


Ответы

Ответ 1



Отличие Set от Map Set хранит набор объектов; от массива и std::vector отличается более быстрой скоростью извлечения. Map является ассоциативным массивом, то есть мы запрашиваем ключ, а получаем значение (то есть полезную нагрузку ключа). Теперь о Multi... Варианты контейнеров с этим названием позволяют хранить: несколько одинаковых элементов (в случае с Multiset), либо несколько значений с одинаковыми ключами, но разной полезной нагрузкой (в случае с Multimap). Одинаковость элементов определяется с помощью операции равенства (operator==). То есть переопределяя этот оператор для всего хранимого типа данных, либо конкретного контейнера, можно изменить критерий равенства элементов.

Как нарисованную картинку вывести в ImageView?

#java #android


Рисую так:

    Bitmap bitmap = Bitmap.createBitmap(w, w, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawARGB(1, 178, 229, 255);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    p.setColor(Color.BLACK);
    p.setStyle(Paint.Style.STROKE);
    p.setStrokeWidth(1);
    canvas.drawCircle(400, 400, 100, p); 


Есть компонент:

ImageView iv = (ImageView) findViewById(R.id.iv);


Как теперь нарисованное отобразить на экране в компоненте ImageView? 
    


Ответы

Ответ 1



Для этого есть метод ImageView#setImageBitmap(Bitmap bitmap). В вашем случае: iv.setImageBitmap(bitmap); Также надо убедиться, что при создании Bitmap её ширина заметна (т.е не 0 или 1 etc), что и было причиной проблемы в данном конкретном случае

Подключение dll файла через интернет

#c_sharp


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


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

    


Ответы

Ответ 1



То, что вы хотите сделать, называется RPC. Другими словами вы отправляете на сервер название функции и её параметры, а в ответ получаете результат выполнения функции. Самый удобный механизм RPC называется SOAP. Удобен он тем, что сервер предоставляет описание функций в виде WSDL файла, на основе которого может быть сгенерирован код на любом языке. К примеру, если сервер поддерживает, то можно вызвать функцию sumOfTwoNumber(5,6) и она вернёт 11. При этом сгенерированный код сам преобразует функцию и параметры в формат понятный серверу, передаст на сервер и получит от сервера ответ. Насколько я помню, в C# можно подключать веб-сервисы (человеческое название SOAP) как простые пакеты. Нужно иметь ввиду, что данные между клиентом и сервером передаются в формате XML, из-за чего трафик может быть большим и медленным. А без интернета функции и вовсе работать не смогут.

Ответ 2



А программа-то что из себя представляет? ASP.Net приложение? А что за Dll? .Net сборка или Win32 dll? В первом случае взломать защиту довольно легко. Во втором см. методы защиты нативных Win32 приложений. Единственный годный вариант защиты для чисто .Net онлайн-приложения - вынесение части функций в какие-нибудь сервисы на Вашем сервере, к которым будут обращаться подписчики со своими аутентификационными токенами.

Изменить цвет кнопки если внесены изменения

#c_sharp #winforms #richtextbox


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


Ответы

Ответ 1



Нужно подписаться на событие richTextBox1_TextChanged: private void richTextBox1_TextChanged(object sender, EventArgs e) { button1.BackColor = System.Drawing.Color.Green; } private void button1_Click(object sender, EventArgs e) { //Сохранение файла button1.BackColor = System.Drawing.Color.Empty; }

Как лучше добавлять класс в div на чистом JavaScript?

#javascript


Как лучше добавлять класс в div на чистом JavaScript (без jQuery)?
    


Ответы

Ответ 1



Element.classList Синтаксис var elementClasses = elem.classList; Методы add( String [,String] ) Добавляет элементу указанные классы remove( String [,String] ) Удаляет у элемента указанные классы item ( Number ) Результат аналогичен вызову сlassList[Number] toggle ( String [, Boolean]) Если класс у элемента отсутствует - добавляет, иначе - убирает. Когда вторым параметром передано false - удаляет указанный класс, а если true - добавляет. Если вторым параметром передан undefined или переменная с typeof == 'undefined', поведение будет аналогичным передаче только первого параметра при вызове toggle. contains ( String ) Проверяет, есть ли данный класс у элемента (вернет true или false) конечно же, у ClassList есть заветное свойство length, которое возвращает количество классов у элемента. const elem = document.querySelector("#clock") //Выведем классы console.log(elem.classList); //DOMTokenList ["example", "for", "you"] //Добавим классы elem.classList.add("ok", "understand"); console.log(elem.classList); //DOMTokenList ["example", "for", "you", "ok", "understand"] //Переключим классы elem.classList.toggle("you"); elem.classList.toggle("he"); console.log(elem.classList); //DOMTokenList ["example", "for", "ok", "understand", "he"] //Проверим класс console.log(elem.classList.contains("example")); //true console.log(elem.classList.contains("lol")); //false //И удалим классы elem.classList.remove("example", "for", "understand", "he"); console.log(elem.classList); //DOMTokenList ["ok"]
*все взято из MDN кому не лень можно и здесь смотреть

Ответ 2



Свойство classList возвращает псевдомассив DOMTokenList, содержащий все классы элемента. item.classList.add('newClass'); // назначаем новый класс

Как обратиться к переменной с id в имени? JS

#javascript


Здравствуйте, есть такой код:

var colors1234 = {
  qwe: qweq
},
    colors1212 = {
  qwe: qweq
};


console.log(colors/*id*/);


Можно ли как-то обратится к такой переменной, если id динамическое?
    


Ответы

Ответ 1



За счёт того, что ваша переменная лежит в глобальной области видимости, можно использовать скобочную нотацию - var colors1234 = { qwe: 'qweq1234' }, colors1212 = { qwe: 'qweq1212' }; const id = 1234; console.log(window[`colors${id}`]); Но лучше вместо пачки переменных формата имя+id сделать такой объект - имя{ id1: ...value... id2: ...value... }

Хеши целых чисел в Python

#python #криптография #хеширование #структуры_данных


Добрый день.

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

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

В чём же дело? Я что-то неправильно понимаю о концепции хорошей хеш-функции? Или
в питоновских словарях и множествах не используется напрямую результат функции hash(),
а как-то дополнительно обрабатывается?
    


Ответы

Ответ 1



Встроенная хеш-функция имеет совсем другие задачи, не связанные с криптографией. Она используется для быстрого и удобного сравнения ключей словарей. Hash values are integers. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0). По поводу идущих подряд ключей: In [37]: hash('aaaa') Out[37]: 5927745366728125705 In [38]: hash('aaab') Out[38]: 3762861188151674483 In [39]: hash('aaac') Out[39]: -5197229166136799781 Для "криптографических" целей стоит обратить внимание на модуль hashlib: In [35]: hashlib.sha512(b'aaa').hexdigest() Out[35]: 'd6f644b19812e97b5d871658d6d3400ecd4787faeb9b8990c1e7608288664be77257104a58d033bcf1a0e0945ff06468ebe53e2dff36e248424c7273117dac09' In [36]: hashlib.sha512(b'123').hexdigest() Out[36]: '3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2' Пример из доки с использованием "соли": >>> import os >>> from hashlib import blake2b >>> msg = b'some message' >>> # Calculate the first hash with a random salt. >>> salt1 = os.urandom(blake2b.SALT_SIZE) >>> h1 = blake2b(salt=salt1) >>> h1.update(msg) >>> # Calculate the second hash with a different random salt. >>> salt2 = os.urandom(blake2b.SALT_SIZE) >>> h2 = blake2b(salt=salt2) >>> h2.update(msg) >>> # The digests are different. >>> h1.digest() != h2.digest() True

как закрыть браузер при помощи javascript или jquery?

#javascript #jquery


делаю таймер и хотелось бы, чтобы когда таймер заканчивался, закрывался браузер.
Возможно ли это? знаю, что можно закрыть текущую вкладку методом close(), но это не то
    


Ответы

Ответ 1



Меня заставили написать ответ :-/ Сделать то, что вы хотите на js нельзя. Как вариант, написанный @Утка Учится Уму - это противоречит элементарным требованиям безопасности например. Простой пример с приколюхой, если бы такое было возможно: представьте, заходите в поисковик, что-то ищите, кликаете на выданную ссылку, попадаете на незнакомый сайт и...он закрывает весь браузер. Как ощущение? А теперь вы запускаете браузер, но т.к. браузер закрылся с той вкладкой, он опять закрывается. Прекрасно, правда? Помогут либо танцы с бубном, либо переустановка браузера. Просто замечательная игра в сапёра - угадай сколько ссылок убьют браузер.

Помогите составить сложный sql запрос

#mysql #sql #база_данных


Есть таблица, одним запросом хочу получить, к примеру, 2 значения - сумма значений
value и сумма значений points, но не могу понять, как составить условия для 2х значений
одновременно, возможно ли это? Вот например сумма values:

`SELECT SUM(value) AS balance FROM db WHERE id>30 AND value>1000`;


Тоже самое для points

`SELECT SUM(value) AS balance FROM db WHERE xxx=2 OR yyy=3`;


А можно ли как то объединить эти 2 запроса в один?
    SELECT SUM(value) AS balance, SUM(point) AS points FROM.... WHERE ??

Всё это при условии, что данные перекликаются и не получится просто соединить эти
2 условия в WHERE
    


Ответы

Ответ 1



Да, можно. Запихните условия where в агрегирующую функцию sum: select id, sum(if(xxx = 2 or yyy = 3, value, 0)) as balance_1, sum(if(id > 30 AND value > 1000, value, 0)) as balance_2 from db group by id

Ответ 2



Вероятно, есть решение поизящнее, но в лоб можно воспользоваться подзапросами - SELECT balance = (SELECT SUM(value) FROM db WHERE id>30 AND value>1000), points = (SELECT SUM(value) FROM db WHERE xxx=2 OR yyy=3`);

UWP как сделать отбрасывание тени для объектов?

#c_sharp #uwp


Надо сделать у кнопки отбрасывание тени. DropShadowEffect не доступен в UWP. Как
быть? Неужели градиентом рисовать...
    


Ответы

Ответ 1



spriteVisual (в code-behind) или создать контейнер для твоего спрайтавизуала перед Button Подробнее можешь почитать тут: https://stackoverflow.com/questions/41303196/how-to-create-a-drop-shadow-effect-for-the-button-in-uwp

Ответ 2



Благодаря UWP Community Toolkit сделать это проще простого

Особенности работы дженериков в Java

#java #ооп #generics


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

public static void main(String[] args) {
    method(4,"s");
}

static  void method(K k1, K k2) {

}


Я думал, что логически ошибка должна быть, ну раз нет, значит такие особенности джавы.
Далее, есть такой код:

public static void main(String[] args) {
    method(new ArrayList(), new Object());
}

static  void method(List k, K k2) {

}


Этот код уже выдает ошибку компиляции. Компилятор говорит, что я в method (List,
java.util.concurrent.Executor) засовываю не то, что надо. Действительно, Object это
вам не Executor. Но вот теперь главный мой вопрос почему в первом случае компилятору
пофиг, что одному и тому же параметризованному типу присваиваются разные типы данных,
а во втором случае компилятор на основе первого аргумента метода вычисляет какой должен
быть аргумент второго метода. Я не понимаю какая логика работает в обоих случаях.

И еще один не менее важный вопрос, если немного изменить второй пример кода вот так:

public static void main(String[] args) {
    method(new ArrayList(), 150);
}

static  void method(List k, K k2) {

}


Теперь никакой ошибки не возникает, причем мы можем пихать любые типы данных а компилятору
все равно! Мы всего лишь изменили List на List. Тут я уже даже теряюсь,
что это значит. Лист который содержит что-то, что наследует К, а что такое К? И почему
в итоге нам разрешено класть в параметры метода что угодно (напоминаю, что в предыдущем
примере с листом это не разрешено).
    


Ответы

Ответ 1



Границы для параметров параметризованных типов работают несколько иначе, нежели для простых типов. В первом случае оба типа могут быть приведены к Object, во втором случае тип может быть только либо Object, либо Executor. Если просто тип может быть легко "снижен" до объекта, то дженерики в параметризованных типах такое по умолчанию не позволяют - пока вы не укажете ? extends K, разрешающее использование наследников K, или ? super K, разрешающее использование предков K. В данном случае вы указали ? extends K, что позволяет использовать Object вместо K, таким образом список параметров метода формируется как List, Object. Могу быть в чем-то неправ, точные ответы на эти вопросы содержатся в JLS (Java Language Specification)