• Как вывести уникальные записи из трёх таблиц?

    @FirststepsRu
    Что то на ум не приходит в один запрос. Надо слить все значения ticker в одну таблицу, затем выбрать только уникальные, и потом из основных таблиц выбрать по ним данные.

    Как-то так:
    CREATE TEMPORARY TABLE all_ticker (`ticker` varchar(16) NOT NULL);
    INSERT INTO all_ticker SELECT ticker FROM table1;
    INSERT INTO all_ticker SELECT ticker FROM table2;
    INSERT INTO all_ticker SELECT ticker FROM table3;
    
    CREATE TEMPORARY TABLE uniq_ticker (`ticker` varchar(16) NOT NULL)
        SELECT ticker FROM all_ticker GROUP BY ticker HAVING count(*) = 1;
    
    SELECT * FROM table1 t1 JOIN uniq_ticker u ON t1.ticker = u.ticker;
    SELECT * FROM table2 t2 JOIN uniq_ticker u ON t2.ticker = u.ticker;
    SELECT * FROM table3 t3 JOIN uniq_ticker u ON t3.ticker = u.ticker;
    
    DROP TEMPORARY TABLE all_ticker, uniq_ticker;
    Ответ написан
    Комментировать
  • Как удалить по шаблону?

    @FirststepsRu
    Может кто-то напишет более красиво, интересно посмотреть.
    LIST="d-auth-service-5f5f466864-bdskb demodent-api-gateway-677bf48f98-gmn2n demomed-client-widget-6c58686f69-qvj9g"
    for L in $LIST; do
    	echo "src: $L"
    	OIFS=$IFS; IFS="-"; N=($L); IFS=$OIFS; Z=${N[0]}
    	for ((I=1; $I < `expr ${#N[*]} - 2`; I=`expr $I + 1`)); do
    		Z=$Z-${N[$I]}
    	done
    	echo "result: $Z"
    done

    Результат
    src: d-auth-service-5f5f466864-bdskb
    result: d-auth-service
    src: demodent-api-gateway-677bf48f98-gmn2n
    result: demodent-api-gateway
    src: demomed-client-widget-6c58686f69-qvj9g
    result: demomed-client-widget

    Через некоторое время еще пришла мысль:
    for L in $LIST; do
          echo "src - $L"
          Z=`echo $L | cut -f1-3 -d'-'`
          echo "result - $Z"
    done
    Ответ написан
    Комментировать
  • Нормально ли сделал тестовое задание на PHP (числа Фибоначчи)?

    @FirststepsRu
    $inputNumbers = [3279, 920, 4181, 8, 337, 13, 918, 4923, 1,
        4448, 8, 4756, 4012, 7467, 89, 21, 9238, 2326, 6453, 89, 4606,
        3413, 3, 9950, 2098, 8579, 4914, 7204, 8875
    ];
    $max_val = max($inputNumbers);
    $result_sum = 0;
    $fib_prev_prev = 0;
    $fib_prev = 1;
    $fib_temp = $fib_prev_prev + $fib_prev;
    for ($i = 0; $fib_temp <= $max_val; $i++) {
    	$found = 0;
    	$fib_temp = $fib_prev_prev + $fib_prev;
    	$fib_prev_prev = $fib_prev;
    	$fib_prev = $fib_temp;
    	if (array_search($fib_temp, $inputNumbers)) {
    		$found = 1;
    		$result_sum += $fib_temp;
    	}
    	echo $i," - ",$fib_temp, ($found==1 ? " found":""),"\n";
    }
    echo "Result sum ", $result_sum, "\n";

    Сначала я хотел сказать, что реализовали не айс. Подумал, что если в исходном массиве сделать очень большое число, то генерируемый массив сожрет всю память :) Но потом долго смеялся, что уже на 90 числе было переполнение 64-бит и тип стал float. Ведь по большому счету Фибоначчи почти что степень двойки. Никакого такого супер массива сгенерить не получится. Ваш код работает, и мой тоже. Даже не берусь оценивать чей лучше. Хотелось бы увидеть мнение общественности. Мне кажется у меня подход проще.
    0 - 1 found
    1 - 2
    2 - 3 found
    3 - 5
    4 - 8 found
    5 - 13 found
    6 - 21 found
    7 - 34
    8 - 55
    9 - 89 found
    10 - 144
    11 - 233
    12 - 377
    13 - 610
    14 - 987
    15 - 1597
    16 - 2584
    17 - 4181 found
    18 - 6765
    19 - 10946
    Result sum 4316

    Возможно по заданию надо это все затолкнуть в массив ? Но чето сформулировано не очень конкретно.
    Ответ написан
  • DELETE FROM list WHERE id = 'id строки в списке дел'. Как мне указать этот id?

    @FirststepsRu
    Ошибка в генерации URL для удаления
    <a href="delete.php?id=notesDelete=' . $row['id']  . '">

    Тут ошибочное id=notesDelete=N. По коду delete.php должно быть delete.php?notesDelete=N
    Но скорее всего хотелось сделать что-то типа
    echo "<a href=delete.php?id=",$row['id'],"&notesDelete=1><button>delete</button></a>";

    Тогда delete.php мог бы выглядеть так
    if (!isset($_GET['id'])) die("Error: not found id parameter");
    $id = intval($_GET['id']);
    if ($id == 0) die("Error: wrong id parameter value");
    if (isset($_GET['notesDelete'])) {
          $dbc = mysqli_connect('localhost', 'root', '', 'notes') or die('Connect error...');
          $query = "DELETE FROM note WHERE id = ".$id;
          $result = mysqli_query($dbc, $query);
          mysqli_close($dbc);
    } else {
          die("Error: no any action found");
    }

    Хотелось сделать важное замечание для начинающего. Ваш изначальный код не защищен от так называемых SQL инъекций. Вот пример кода
    $id = intval("SELECT nothing"); var_dump($id);
    $id = intval("1312; DELETE something"); var_dump($id);
    $h = "DELETE FROM note WHERE id = '$id'";
    var_dump($h);
    $id = "10'; DROP DATABASE mysql; SELECT * FROM note WHERE id='1";
    $h = "DELETE FROM note WHERE id = '$id'";
    var_dump($h);

    Выведет
    int(0)
    int(1312)
    string(34) "DELETE FROM note WHERE id = '1312'"
    string(80) "DELETE FROM note WHERE id = '10'; DROP DATABASE mysql; SELECT * from note id='1'"

    То есть если злоумышленник подставит в URL текст с DROP DATABASE то сможет нарушить работу программы или получить какие-то секретные данные.
    Я в коде продемонстрировал как можно от этого себя обезопасить, это принудительно привести тип входных данных к требуемому для работы, в данном случае к целому числу intval(). Таким образом все непонятное будет обрезано или пребразовано к 0. Для строковых выражений обязательно применять экранирование с помощью mysqli_real_escape_string().
    Но более лучшей практикой в таком случае будут так называемые "подготовленные запросы SQL" о создании которых упомянул alexalexes, но не пояснил почему так надо делать.
    Ответ написан
    1 комментарий
  • Стоит ли учить Си?

    @FirststepsRu
    Сейчас много пришлось писать на Си и я пожалуй соглашусь с Торвальдсом. Очень сложно удержаться и не начать применять классы и прочие плюшки. Везде нужен контроль за памятью, указателями, переполнениями чего-то, нет конструкторов, деструкторов, нельзя что-то перегрузить. Любые разработчики на высокоуровневых языках типа Java, Python, Go, PHP где-то даже С++ вообще могут не знать как работает что-то под капотом. Си разработчики находятся чуть более выше чем ассемблер и поэтому должны понимать как все работает на самом низком уровне. Такие знания нужны для разработки библиотек, драйверов, чего-то для встраиваемых систем где нужны скорость и маленький размер. А так как компаний, которые этим занимаются не много, то и вакансий мало.
    Ответ написан
    1 комментарий
  • Как переделать код в код с процедурами?

    @FirststepsRu
    Вынес код вывода и подсчета в отдельные функции как один из вариантов.
    #include <stdio.h>
    
    void print_line(int *a, int line) {
    	for (int j = 0; j < 4; j++) {
    		printf("%d\t", a[j]);
    	}
    	printf("\n");
    }
    
    int sum_line(int *a, int line) {
    	int sum = 0;
    	for (int j = 0; j < 4; j++) {
    		sum += a[j];
    	}
    	return sum;
    }
    
    int main() {
        int a[4][4] = {{4, 5, 1,  0 },
                       {1, 8, 0,  2 },
                       {8, 5, 1,  -5},
                       {6, 4, -3, 0 }};
    
        for (int i = 0; i < 4; i++) {
            print_line(&a[i][0], i);
        }
    
        for (int i = 0; i < 4; i++) {
            printf("\nСтрока - %d сумма - %d",i, sum_line(&a[i][0], i));
        }
    }
    Ответ написан
  • Как задать права доступа к симлинку?

    @FirststepsRu
    Какая разница кто владелец файла, важно какой уровень доступа к нему. Скорее всего папка /etc/vendorname или сам файл закрыт для чтения (например chmod 700 или 600)
    Для того, чтобы все могли читать этот файл надо сделать из под root (из под пользователя user не хватит привилегий)

    chmod a+r /etc/vendorname
    chmod a+r /etc/vendorname/file.txt

    Потом уже пользователь сможет сделать симлинк. Если нельзя разрешать всем видеть этот файл, то тогда надо пользователя user добавить в группу root. И разрешить читать этот файл группе через g+r. Если этот файл генерится заново, то возможно каждый раз привилегии будут слетать, потребуется изменение программы, которая создает этот файл.
    Ответ написан
  • Как сделать чтобы слово выводило в столбик?

    @FirststepsRu
    Видимо имелось в виду, что d будет индексом буквы, а получилось что стало счетчиком букв.

    #include <iostream>
    using namespace std;
    int main() {
    	char s[50];
    	int d = 0;
    	cin >> s;
    	while (s[d]) cout << s[d++] << endl;
    }
    Ответ написан
    Комментировать
  • Как реализовать опциональный ввод?

    @FirststepsRu
    Создание if для ввода b это правильно, но не до конца. Надо определить в main аргументы командной строки, тогда при задании какого-то аргумента в командной строке будет выполняться условие внутри программы. Правда код на Си :)

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv) {
        int opt_b = 0;
        if (argc == 1) printf("No options\n");
    
        if ((argc > 1) && (strcmp(argv[1],"b")==0)) {
             opt_b = 1;
        }
    
        if (opt_b == 1) {
            printf("Option b\n");
        }
        return 0;
    }


    Потом при вызове программы задаете опции.

    root@localhost:~# ./a.out
    No options

    root@localhost:~# ./a.out b
    Option b
    Ответ написан
    Комментировать
  • Почему не работает TCP чат?

    @FirststepsRu
    По коду быстро понять сложно, не зная что было до изменений и какие изменения были внесены. По задаче эхо сервер это не чат. Задача эхо сервера отправлять клиенту теже данные, что он ему присал, это его смысл. Смысл чата в обратном, надо отправлять данные от клиента всем другим подключенным клиентам на сервере, кроме этого клиента (чтобы не было эха).

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

    Попробуйте изучить код чата реализуемого в https://eax.me/libevent/, за одно и изучите великолепную библиотеку. Создание потока на каждое соединение приводит к быстрому исчерпанию ресурсов и приводит к так называемой проблеме C10K (10000 соединений). В мире когда миллиарды клиентов могут обращаться к серверу решения по схеме поток на соединение имеют архитектурный изъян.
    Ответ написан
    Комментировать