здравствуйте, нарыл тут на просторах реализацию сишной функции strlen : /* Magic numbers for the algorithm */
#if LONG_BIT == 32
static const unsigned long mask01 = 0x01010101;
static const unsigned long mask80 = 0x80808080;
#elif LONG_BIT == 64
static const unsigned long mask01 = 0x0101010101010101;
static const unsigned long mask80 = 0x8080808080808080;
#else
#error Unsupported word size
#endif #define LONGPTR_MASK (sizeof(long) - 1) /*
* Helper macro to return string length if we caught the zero
* byte.
*/
#define testbyte(x) \
do { \
if (p[x] == '\0') \
return (p - str + x); \
} while (0) size_t
strlen(const char *str)
{
const char *p;
const unsigned long *lp; /* Skip the first few bytes until we have an aligned p */
for (p = str; (uintptr_t)p & LONGPTR_MASK; p++)
if (*p == '\0')
return (p - str); /* Scan the rest of the string using word sized operation */
for (lp = (const unsigned long *)p; ; lp++)
if ((*lp - mask01) & mask80) {
p = (const char *)(lp);
testbyte(0);
testbyte(1);
testbyte(2);
testbyte(3);
#if (LONG_BIT >= 64)
testbyte(4);
testbyte(5);
testbyte(6);
testbyte(7);
#endif
} /* NOTREACHED */
return (0);
}
можете прокомментировать зачем такой треш?
Ответ
Это реализация strlen, которая работает не побайтно, а пословно. Для того она и сделана: чтобы ради пущей эффективности читать и анализировать данные из памяти не одиночными байтами, а сразу выровненными словами длиной 32 или 64 бита. Для достижения выравнивания начальная часть строки (до требуемой границы выравнивания), обрабатывается побайтно, то есть обычным способом. Далее строка читается пословно. Каждое прочитанное слово обрабатывается при помощи следующего бит-хака if ((*lp - mask01) & mask80)
который анализирует все прочитанное слово (т.е. фактически "параллельно" анализирует все его байты) и приблизительно отвечает на вопрос о том, есть ли в слове *lp нулевой байт. Если данная проверка дает положительный ответ, то код под этим if при помощи макро testbyte выясняет уже, в какой точной позиции он находился. "Приблизительность" проверки в данном случае заключается в том, что условие в if иногда может дать положительный ответ даже в случае слова без нулевого байта - если в слове присутствуют байты с единицей в старшем бите. Т.е. эта проверка допускает "ложные срабатывания" и, как следствие, вызывает ненужную побайтовую проверку через testbyte, но на корректность результата это не влияет. Строки, составленные из символов с кодами не выше 128 будут обрабатываться эффективно. Слова же, в которых нулевой байт содержится, этой проверкой будут заведомо обнаружены. Более сложная версия условия, основанная на тех же масках if ((*lp - mask01) & ~*lp & mask80)
гарантировала бы точное определение наличия нулевого байта в слове, но авторы, очевидно, решили, что эффективнее будет работать именно их приближенный вариант (скорее всего потому, что код рассчитан на строки из символов латинского алфавита). Теоретически, такая реализация обладает одной формальной проблемой: при пословном чтении содержимого строки может получиться так, что последнее читаемое слово будет "торчать" за пределы самой строки и выделенной для нее памяти. На практике это не приводит к проблемам, так как выделение и/или защита памяти обычно делаются по границам, выровненным как минимум до размера полного слова. Однако подобные "вылеты" могут вызвать жалобы от средств динамического анализа кода, типа valgrind.
Что такое адрес произвольной рассылки (anycast)? Для чего он нужен?
Ответ
Any - любой, cast - бросать Anycast - технология маршрутизации, предоставляет отправку пакета "первому попавшемуся" в anycast группе. Т.е. кто первый получил пакет - его и обрабатывает. Остальные участники Anycast группы этого пакета уже не увидят. Если простым языком, то один и тот же IP-адрес назначается нескольким серверам, расположенным в разных местах и когда делается запрос по адресу - выбирается ближайший (чем меньше точек прохода пакета, тот ближе) Более подробно в статье с Habrahabr:
Смысл метода Anycast заключается в анонсировании одинакового префикса
IP-адресов одновременно из нескольких точек сети через протокол BGP. В
результате данные передаются по наиболее короткому маршруту — на
ближайший узел, которому присвоен анонсированный IP-адрес. При этом
понятие «короткий маршрут» в данном случае трактуется не в
географическом, а в топологическом смысле.
В чем смысл текстовых шаблонов T4? По сути, этого же можно добиться с помощью динамической компиляции. Доступ к исходному коду так же не даёт никаких преимуществ, так как править его не имеет смысла из за перегенерации.
Ответ
Если вы имеете в виду T4, то их смысл — встроенный в систему шаблонизатор/DSL. T4 используется в двух вариантах: времени компиляции и времени выполнения. T4 времени выполнения обычно используется как шаблонизатор, и означает, что вы можете легко генерировать текстовые файлы, в которых большая часть текста постоянна, а куски необходимо генерировать программно. Простой пример — шаблон письма, в который нужно вставить имя адресата, адрес и наименование товара. Но гораздо более интересным является T4 времени разработки. Эта штука позволяет вам генерировать код на этапе компиляции (точнее, даже до неё). То есть, у вас появляется ещё одно прекрасное (хотя и немного неуклюжее — если не сравнивать с шаблонной магией Александреску) средство для настоящего метапрограммирования. Причём в отличие от решений, которые вы могли бы соорудить на коленке, T4 встроен в Visual Studio, и сгенерированные файлы просто видны в дереве Solution Explorer'а, и подхватываются компилятором. T4 используется для кодогенерации многими проектами, начиная с Entity Framework. Вот здесь ещё достаточно впечатляющий список. Вот, например, пример того, как автоматически генерировать определения Dependency Property. (Я тоже использовал T4 для генерации из текстового представления XAML-словарей для локализации.)
Кодогенерация времени выполнения и правда не лучший метод использования T4. Для этих целей лучше подходит CodeDOM (или, кажется, Roslyn API). А для кодогенерации времени компиляции доступ к сгенерированным исходникам очень важен, например, для отладки.
Дополнение к вопросу из комментария. Да, можно в шаблоне генерировать другой шаблон. Например, такой вот шаблон <#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".tt" #> <# string open = "<" + "#" + "@", close = "#" + ">"; #> <#= open #> template debug="false" hostspecific="false" language="C#" <#= close #>
<#= open #> assembly name="System.Core" <#= close #>
<#= open #> import namespace="System.Linq" <#= close #>
<#= open #> import namespace="System.Text" <#= close #>
<#= open #> import namespace="System.Collections.Generic" <#= close #>
<#= open #> output extension=".cs" <#= close #> class Test
{
public int i;
}
порождает подчинённый шаблон <#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #> class Test
{
public int i;
}
который в свою очередь порождает класс class Test
{
public int i;
}
Никаких специальных действий выполнять не нужно, просто добавьте шаблон T4 через Add → New item → Text Template (не Runtime Text Template!)
В T4-файл положите текст шаблона, как он представлен выше, и вы получите такую вот необычную структуру вашего solution'а:
В чем разница между len() и .__len__()? И могут ли они возвращать разные значения?
Ответ
__len__ это магический метод, который реализует len операцию.
Как и любой другой специальный метод, он вызывается специальным образом (должен быть определён в самом классе), то есть len(o) не всегда эквивалентно o.__len__(). Подробнее в ответе о магических методах Дополнительно, значения len() ограничены sys.maxsize >>> import sys
>>> class Big:
... def __len__(self):
... return sys.maxsize + 1
...
>>> len(Big())
Traceback (most recent call last)
...
OverflowError: cannot fit 'int' into an index-sized integer
>>> Big().__len__()
9223372036854775808
На практике, иногда полезно иметь последовательность с большой длиной:
Get the highest possible gmtime for any architecture
Weighted random sample in python
HR менеджер дал тестовое задание. Я выполнил. В ответ он сказал, что
я получил только краткий фидбек - не понравилось качество и стиль реализации.
Хочу вашего совета, что я не так написал.
Вот задание: Тестовое задание #1: Версии ПО: PHP 5.3-5.6 Необходимо реализовать функцию, которая произведет чтение данных файла и вернет обработанные данные в указанном виде. Функция должна:
- Считать данные с файла
- Разбить данные по строкам в массив
- Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа
- Суммировать числа в каждой строке
- Отсортировать полученные суммы в порядке убывания
- Вернуть результат Пример кода: # Путь к файлу данных $file = __DIR__ . '/datalist.txt';
# Передаем данные в функцию и получаем результат $result = getResult( $file );
# Отображаем результат echo '
';
var_export( $result ); function getResult ( $file ) {
# @TODO Реализовать... } Пример результата работы функции: array ( 82 => 16396, 19 =>
16169, 71 => 15864, 73 => 15224, 81 => 14244 ...
Кусок файла datalist.txt: 55 NTfy 591 405 kLj 48 644 768 164 ubd 837 oTft GPQV 163 ja 445 961
431 574 168
375 380 427 670 610 284 765 48 687 660 377 333 914 70 146 328 301 925 266
620 237 137 584 427 308 939 660 917 59 864
j hHo 279 tqpg 617 870 CoNJ 173 czgW 301 299 134 820 625 U 369 165 hutPN jiq 31 575 46 NS 397 378 954 764
Как я это реализовал: # Путь к файлу данных
$file = __DIR__ . '/datalist.txt';
# Передаем данные в функцию и получаем результат
$result = getResult($file);
# Отображаем результат
echo '
';
var_export($result); function getResult($file) {
#Считать данные с файла.
#Разбить данные по строкам в массив
$line = file($file);
$i = 0;
foreach ($line as $value) {
$ArrayLine = explode(' ', $value);
foreach ($ArrayLine as $Record) {
$result[$i] = 0;
#Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа
$CheckString = preg_replace('~[^A-Za-z]+~', '', $Record);
if (strlen($CheckString) > 0) {
unset($result[$i]);
break;
};
$res = (int) $Record;
#Суммировать числа в каждой строке
$result[$i] += $res;
}
$i++;
}
#Отсортировать полученные суммы в порядке убывания
arsort($result);
return $result;
}
Ответ
Код /**
* Функция производит чтение данных из файла и возвращает обработанные данные согласно алгоритму
* - Считать данные с файла
* - Разбить данные по строкам в массив
* - Отфильтровать массив таким образом, чтобы в нем остались лишь строки содержащие только числа
* - Суммировать числа в каждой строке
* - Отсортировать полученные суммы в порядке убывания
* - Вернуть результат
*
* @param string $file
* @return array
*/
function getResult($file) {
$numbers = []; $handle = @fopen($file, 'r');
if ($handle) {
// Читаем файл построчно
while (($buffer = fgets($handle, 4096)) !== false) {
// Удаляет пробелы (или другие символы) из начала и конца строки
$buffer = trim($buffer); if (preg_match('/^[\d ]+$/', $buffer)) {
// Разбиваем строку на числа, складываем получившийся массив чисел и записываем в массив
$numbers[] = array_sum(explode(' ', $buffer));
}
}
} // Сортируем массив по возрастанию (без сохранения отношений с ключами)
rsort($numbers); return $numbers;
} $result = getResult(__DIR__ . '/datalist.txt'); print_r($result);
Комментарии к коду:
По входному файлу, в примере, делаю следующий вывод. Функция разработана с учетом того, что числа только положительные и целые, и внутри слов нету чисел, например, oT89ft. И число не может идти рядом со словом, например, 200NTfy (то есть будет ли он считаться числом после удаление «нечисел»).
Хоть в алгоритме указан шаг Разбить данные по строкам в массив, он пропускается, чтобы не «забивать» память (не происходило переполнение памяти). Потом что строк в файле может быть очень много. Чтение происходит построчно и в массив сразу вычисляется и записывается сумма.
Длина строки при чтении ограничена length - 1 байт
Не стал «доходить по паранойи»: сортирую массив встроенной в PHP функцией и не стал делать какой-нибудь composer-пакет с тестами.
Комментарии на русском... Желательно на англ. писать, если компании не против, где работать будете — потом пригодится :)
Дополнительная информация При написании (форматировании кода) я стараюсь следовать PHP Standards Recommendations, в частности:
PSR-1: Basic Coding Standard
PSR-2: Coding Style Guide
Изучите информацию на сайте — пригодится. И всегда обращайтесь и изучайте информацию по PHP на официальном сайте. Документация на русск. или англ. языках. И не бойтесь ошибаться! Задавать любые вопросы на Stack Overflow!
Как в переменную записать результат быстрейшего метода(два раза вызывается один метод с разными передаваемыми значениями, нужен результат быстрейшего метода)?
Ответ
Судя по метке, метод у вас асинхронный. В таком случае можно воспользоваться Task.WhenAny() public async Task FooAsync(int x)
{
//...
} ... var task1 = FooAsync(1);
var task2 = FooAsync(2);
var fastestTask = await Task.WhenAny(task1, task2);
var result = fastestTask.Result;
Однако может так случиться, что какой-либо таск завершится быстрее из-за исключения. В таком случае нужно снова вызвать Task.WhenAny() для оставших тасков. В общем случае решение может выглядеть так: var task1 = FooAsync(1);
var task2 = FooAsync(2);
var task3 = FooAsync(3);
var tasks = new List>() { task1, task2, task3 };
int result;
while (tasks.Count > 0)
{
var fastestTask = await Task.WhenAny(tasks);
if (fastestTask.IsCompleted)
{
result = fastestTask.Result;
break;
}
else // если таск упал или был отменен
{
tasks.Remove(fastestTask);
}
}
Ждать или отменять оставшиеся таски, если один из них упал -- зависит от задачи. Например, если вы хотите получить цену одной и той же акции из нескольких источников, то даже если один из источников недоступен, вы дождетесь ответа другого источника. В случае если вы хотите получить цену разных акций из одного и того же источника, то, вероятно, имеет смысл отменить оставшиеся таски, поскольку понятно, что если источник недоступен, то остальные задачи тоже упадут.
Хочу реализовать простейший пример. Есть два числа в двоичной системе 0011 и 0101. Хочу применить к ним операцию "ПОБИТОВОЕ ИЛИ". Результат вывести в виде двоичного числа. Должно получиться 0111, получаю 73.
Почему так? #!/bin/bash
AA=0011
BB=0101
CC=$(($AA | $BB))
echo "Result: " $CC
Ответ
Двоичные числа в bash задаются как 2#число. Выводить в двоичном виде результат bash не умеет, можно воспользоваться bc #!/bin/bash
AA=2#0011
BB=2#0101
CC=$(($AA | $BB))
echo -n "Result: "
printf "%04d" `echo "obase=2;$CC" | bc`
Допустим, я написал функцию: function foo() {
alert("Hello, world!");
}
Почему когда я пытаюсь вызвать ее спустя некоторое время, она вместо этого вызывается сразу же? setTimeout(foo(), 10000);
И то же самое - с обработчиками событий? Пытался делать вот так: el.onclick = foo();
el.addEventListener("click", foo());
createButton({
name: "show alert",
onClick: foo(),
});
Ответ
Возможно, вы написали скобки около имени функции - foo() - случайно. А возможно, вы думаете что именно этими скобками функция отличается от переменной. В любом случае, ошибка скрыта именно тут. Кратко: уберите лишние скобки и все заработает.
Javascript вычисляет выражения изнутри-наружу (как и многие другие языки). Очевидные примеры из математики: в выражении 2 + 2 * 2 сначала выполняется умножение, а потом - сложение, а в выражении (2 + 2) * 2 - наоборот. Когда вы пишите foo() - это оператор вызова функции. Это- такая же часть выражения как и любая математическая операция. И если где-то внутри выражения есть вызов foo() - то функция foo будет вызвана независимо от того что написано снаружи. Так, в примере setTimeout(foo(), 10000); сначала вызывается foo(), а потом результат вызова foo() (обычно это какой-нибудь undefined) передается в setTimeout: setTimeout(undefined, 10000). С точки зрения интерпретатора Javascript это не ошибка: он же не знает что такое foo, он просто послушно делает что вы ему сказали. Если вам не нужно вызывать функцию - то не надо ее вызывать. Просто убираем скобки около имени функции - и теперь она передается как есть, без вызова: setTimeout(foo, 10000);
el.onclick = foo;
el.addEventListener("click", foo);
createButton({
name: "show alert",
onClick: foo,
});
Вызовут ее уже в другом месте, когда придет время. (Кстати, такая переданная куда-то функция обычно называется колбеком, callback или функцией обратного вызова). Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.
Создал 2 класса. От одного наследовал другой. Вот код: class Program
{
static void Main(string[] args)
{
Manager man = new Manager("", "", 0, 0);
}
} class Employee
{
public string Surname { get; set; }
public string Name { get; set; }
public int Age { get; set; } public Employee(string sName, string MyName, int MyAge)
{
Surname = sName;
Name = MyName;
Age = MyAge;
}
} class Manager : Employee
{
public int Pay { get; set; } public Manager(string s, string n, int a, int p)
{
Surname = s;
Name = n;
Age = a;
Pay = p;
}
}
В унаследованном классе заполняю напрямую свойства из первого. Но почему то ругается на конструктор класса Manager.
Error CS7036 There is no argument given that corresponds to the
required formal parameter 'sName' of 'Employee.Employee(string,
string, int)'
Что то не пойму что не так?
Ответ
В классе Employee у вас нет конструктора без параметров, так что вы должны явно указать конструктор Employee, соответствующий конструктору Manager, и передать в него параметры. Создать объект класса Employee без вызова конструктора (и, соответственно, без передачи в него параметров) не получится: public Manager(string s, string n, int a, int p)
: base(s, n, a) // будет вызван Employee(string, string, int)
{
// все свойства, кроме Pay, инициалируются в конструкторе базового типа
Pay = p;
}
Как на java создать такой массив как здесь в примере на пхп? $arr2 = array(
'Авто' => array(
'KIA',
'BMW',
'MAZDA',
'OPEL'
),
'Краска' => array(
'Красная',
'Зеленая',
'Черная'
)
);
Ответ
С помощью Map и List Map> arr2 = new HashMap<>();
arr2.put("Авто", Arrays.asList("KIA", "BMW", "MAZDA", "OPEL"));
arr2.put("Краска", Arrays.asList("Красная", "Зелёная", "Чёрная"));
Как создать в классе список, который имеет несколько значений?
Грубо говоря, сделать что-то, на подобие: List array = new List();
array.Add(4,5,4.3,5);
Console.WriteLine(array[0][2]);
Ответ
Tuple List> array = new List>();
array.Add(Tuple.Create(4,5,4.3,5));
Console.WriteLine(array[0].Item3);
ValueTuple: List<(int,int,double,int)> array = new List<(int,int,double,int)>();
array.Add((4,5,4.3,5));
Console.WriteLine(array[0].Item3);
Есть основное приложение WinForms в котором ведётся парсинг интернет ресурса с записью необходимых данных в двумерный массив string[5000, 50] Где 1й столбец строки это ссылка, а остальные столбцы данные с ресурса. Как только набирается строка c данными , данные этой строки сгруппировано выводятся в окне приложения. Как мне эти данные передавать в массив другого приложения WinForms по интернету и так же выводить ? Главный вопрос, как передавать эти данные c записью в массив ? Самостоятельно искал, читал немного про сокеты, но пока каша в голове и не знаю про подводные камни. Хотелось бы как то тупо, при заполнении строки массива в главном приложении, сразу эту строку массива передавать в массив удалённого приложения.
Ответ
Я мог бы вам предложить один из вариантов организации данного функционала: Логика : 1) Серверная часть Ваш Parser после анализа полученных данных и формирования массива значений (рекомендую использовать коллекции в место статичного массива)
сериализуется в json(или XML формат) строку и добавляет их в базу данных MySQL (локальную или удалённую) (с одновременной проверкой наличия там таких данных)
- SQL запрос для организации структуры базы данных для ваше случая должна быть примерно таковой CREATE DATABASE IF NOT exists parsersystem;
use parsersystem;
CREATE TABLE IF NOT exists Procedures (
number int AUTO_INCREMENT,
id int,
jsonData TEXT,
ts_create timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
ts_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (number)
);
где number это автоинкриментное поле (уникальный номер записи в БД) id - уникальный специфичный номер записи (заданный пользователем) jsonData - сериализация любых данных в том числе и массива ваших значений ts_create - дата и время создание записи ts_update - дата и время обновления записи
MySQL сервер настраивается таким образом чтобы к нему имели доступ клиенты через интернет либо локальную сеть (в зависимости от ваших нужд)
2) Клиенты
Клиентское приложение будь то Desktop, Android или другое, не имеет связи непосредственно с вашим серверным Parser приложением, а обращается к открытой MySQL базе (закрытой по желанию паролем), на предмет наличия новых записей, это становится возможным при использовании поля ts_create - которое отражает время создание записи
Логика:
клиент периодически делает запрос к базе данных
примерно такой
SELECT * FROM Procedures WHERE ts_create > TIMESTAMP (время последней
добавленной клиентом записи) ORDER BY ts_create DESC
таким образом клиент получит только новые записи из таблицы
на стороне клиента происходит десереализация jsondata и формирование своей локальной копии массива (идентичного тому что на стороне сервера)
клиенту следует хранить дату и время последней добавленной записи для последующих запросов
Преимущество такого подхода :
независимость клиентской и серверной части приложения, (данные хранятся отдельно в БД)
нет необходимости в организации специфического протокола общения (сервер -клиент) при использовании подхода передачи при помощи сокетов
Предположим что мы имеем некий класс описывающий модель наших данных public class Procedure(){
public String Name { get; set; }
public List Data { get; set; }
}
А также мы на стороне сервера имеем набор данных (коллекцию) public List procedures;
Для записи в базу данных такой конструкции стоит применять примерно такой метод: public AddProceduresToDataBase(List procedureList) {
string Connect = "Port=3306; Database=parsersystem;Data Source=127.0.0.1;Password=mysql_password;
MySqlConnection myConnection = null;
try
{
myConnection = new MySqlConnection(Connect); myConnection.Open();
}
catch (Exception e)
{
myConnection.Close();
Console.Out.WriteLine("Ошибка доступа к базе данных");
} foreach (var proc in procedureList)
{
var json = new JavaScriptSerializer().Serialize(proc);
// Экранируем спец символы
json = json.Replace(Convert.ToChar(0171) + "", "")
.Replace(Convert.ToChar(0187) + "", "")
.Replace("\\\"", "")
.Replace("\\","\\\\");
MySqlCommand myCommand_add = new MySqlCommand(@"INSERT INTO Procedures(id,jsondata,ts_create,ts_update) VALUE (" + сгенерить нужно ID + "+ json + "',null,null);", myConnection);
myCommand_add.ExecuteNonQuery();
} myConnection.Close(); //Обязательно закрываем соединение!
} Для чтения коллекции из базы данных стоит использовать примерно такой метод public List GetProcedures() {
string Connect = "Port=3306; Database=parsersystem;Data Source=127.0.0.1;Password=mysql_password;
MySqlConnection myConnection = null;
try
{
myConnection = new MySqlConnection(Connect); myConnection.Open();
}
catch (Exception e)
{
myConnection.Close();
Console.Out.WriteLine("Ошибка доступа к базе данных");
} string CommandText = "SELECT * FROM Procedures ";
MySqlCommand myCommand = new MySqlCommand(CommandText, myConnection); MySqlDataReader MyDataReader;
MyDataReader = myCommand.ExecuteReader(); List procedures = new List();
String jsonData; while (MyDataReader.Read())
{
try
{
jsonData = MyDataReader.GetString(2); // Читаем jsondata из 2го столбца таблицы
Procedure newProcedure = new JavaScriptSerializer().Deserialize(jsonData);
procedures.Add(newProcedure);
}
catch
{
Console.Out.WriteLine("Ошибка разбора JSON данных о процедуре");
}
}
MyDataReader.Close();
myConnection.Close();
return procedures;
} ПС. естественно методы нужно дорабатывать, внедрить проверку на наличие уже такого рода данных в БД, расширить функционал чтения для получения новых записей , но это я уже оставляю вам.
ПС. так же тут в принципе показаны примеры сериализации и десиарилизации данных в JSON
Подскажите, пожалуйста, расширение или что-то подобное, что сможет сохранить мои личные CSS для сторонних сайтов. К примеру, у ВКонтакте background: #edeef0;, а я хочу поменять на свой цвет, чтобы при перезагрузке страницы дописывались стили через !important или inline
Ответ
Расширения для браузера - Stylish Ответ дан пользователем: diraria
У меня есть 5 инпута, нужно сделать так, чтобы если одно из них не заполнить, то сообщение не должно быть отправлено.
document.querySelector(".btn-info").addEventListener("click", function(){
var required = document.querySelectorAll(".required");
if (required.val == "") {
alert("please fill all the columns");
}
});
.required {
display:block;
padding-bottom:10x;
}
Ответ
Так как querySelectorAll возвращает коллекцию элементов, то проверка required.val == "" бессмысленна, ибо берется val (которого и одиночного-то элемента нет), которого в коллекции нет. Соответственно можно пробежать по коллекции и просмотреть значение value у элементов:
document.querySelector(".btn-info").addEventListener("click", function(){
let required = document.querySelectorAll(".required");
let isAllFilled = true;
for (let i = 0; i < required.length; ++i) {
if (required[i].value.trim() == "") {
isAllFilled = false;
break;
}
}
if (!isAllFilled)
alert("please fill all the columns");
});
.required {
display:block;
padding-bottom:10x;
}
Зачем нужен спецификатор private в C++, если по умолчанию итак все функции и переменные являются закрытыми?
Ответ
Например, потому, что в структуре по умолчанию все функции и поля являются открытыми Кроме того, текстовый порядок полей влияет на порядок их инициализации в конструкторе! Поэтому просто так переставлять поля класса нельзя, это может изменить смысл программы. Пример. Допустим, что мы хотим, чтобы поле len было открытым, а поле data — закрытым. class MyString
{
public:
unsigned len;
private:
char* data;
public:
MyString(const char* s) :
len(std::strlen(s)),
data(new char[len + 1])
{
std::memcpy(data, s, len + 1);
}
// ...
};
Мы не можем переставить местами len и data, потому что инициализаторы в конструкторе выполняются в том порядке, в котором указаны поля, а не в том порядке, в котором они написаны в коде! А значит, без private не обойтись.
Если я выделяю память для некоторого типа T - пусть это в шаблоне, скажем - template
char* alloc(size_t n) { return new char[n*sizeof(T)] ; }
то места гарантированно хватит для n элементов с типом T или нет? Какие-то проблемы из-за выравнивания могут быть? И если могут - то как их правильно решить? Дополнение - по совету @VladD я ппробовал выделить память с особыми требованиями к выравниванию: #include
#include using namespace std; struct alignas(256) D {
char a;
char b;
}; template
void* alloc(size_t n) {
return reinterpret_cast(new
aligned_storage[n]);
} template
int allocSize() {
cout << "sizeof = " << sizeof(T) << ", alignof = " << alignof(
T) << endl;
cout << "type = " << typeid(typename
aligned_storage::type).name() << endl;
return sizeof(typename
aligned_storage::type);
}
int main() {
cout << allocSize() << endl;
cout << alloc(5) << endl;
}
GCC это не смог отработать - https://ideone.com/dgo75h. Но Visual Studio нормально отработал, но выдал: sizeof = 256, alignof = 256
type = union std::_Align_type
256
004A1258
т.е. понял и размер, и выравнивание, но адрес дал выровненный явно не на 256. Мне это выравнивание не нужно, это так, игры - но тем не менее получается, что так выделять память не получается?
Ответ
По идее, вам нужно std::aligned_storage Должно по идее работать так: template
char* alloc(size_t n)
{
return new aligned_storage[n];
}
Проблемы из-за выравнивания с простым подходом очевидны: new char[] не знает ваших требований по выравниванию, и может выделить неправильно выровненную память.
Для выделения объектов в вашей памяти вам понадобится placement new. Вам должен пригодится std::align, использование которого описано здесь
Обновление: я перепроверил, и на самом деле new не соблюдает кастомные требования по выравниванию. Поэтому нужно делать выравнивание самостоятельно, при помощи std::align. Получается вот что: // подсчёт длины нужной аллокации
template
size_t aligned_char_size(size_t n)
{
size_t result = n * sizeof(T);
bool is_overaligned = alignof(T) > alignof(std::max_align_t);
if (is_overaligned)
result += alignof(T) - 1;
return result;
}
Применяем: struct alignas(1024) S
{
};
// выделёем память на 3 экземпляра
size_t total_space = aligned_char_size(3);
void* p = new char[total_space];
std::cout << p << std::endl; // получаем выровненный указатель при помощи std::align
void* allocated_item = p;
size_t remaining_space = aligned_char_size(3);
if (std::align(alignof(S), sizeof(S), allocated_item, remaining_space))
{
std::cout << allocated_item << std::endl;
std::cout << (size_t)allocated_item % alignof(S) << std::endl;
}
else
{
std::cout << "Impossible" << std::endl;
}
Результат на Visual Studio 2017: 000002333DF15950
000002333DF15C00
0
Если убрать alignas(1024), получаем 000002A27FD2ECD0
000002A27FD2ECD0
0
Есть dll без исходников, для нее есть интерфейс на delphi. Стоит задача подружить эту библиотеку с 1С. На сколько понял с прочитанного в интернете, на основе интерфейса можно сделать dll по COM технологии. Пример интерфейса: unit Unit1;
interface uses Windows,
Messages,
Classes,
SysUtils,
Forms;
type
TBonusCountersPrintQuery = packed record
Card: array[0..15] of char;
end; TListCountersPrint = packed record
Lines: array[0..PACKET_COUNTERS_PR_MAX_LINE_COUNT - 1] of TCounterLine;
end; TCounterLine = packed record
LineNo: word;
IsLast: byte;
Num_Counter: word;
N_Counter: array[0..9] of char;
Value_Counter: Cardinal;
end; type
THWE_ProcessBonusListCountersPrint = function(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; stdcall; function ProcessBonusListCountersPrint(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer; stdcall; implementation var
HWE_ProcessBonusListCountersPrint : THWE_ProcessBonusListCountersPrint; function init_dynamic(ALibrary: string): Boolean;
begin
hLib := SafeLoadLibrary(ALibrary); Result := (hLib <> 0); if Result then
begin @HWE_ProcessBonusListCountersPrint := GetProcAddress(hLib, 'ProcessBonusListCountersPrint'); Result := Assigned(HWE_ProcessBonusListCountersPrint);
end;
end; function ProcessBonusListCountersPrint(vBonusCountersPrintQuery: TBonusCountersPrintQuery; var vListCountersPrint: TListCountersPrint): Integer;
begin
result := HW_FAILURE;
if hLib <> 0 then result := HWE_ProcessBonusListCountersPrint(vBonusCountersPrintQuery, vListCountersPrint);
end; initialization finalization end.
Как правильно написать такую dll, чтобы функция из примера была доступна из 1С?
Ответ
Ваша библиотека будет связующим звеном между 1C и сторонней библиотекой без исходного кода: 1C -> ВашаБиблиотекаCOM -> СтороняяБиблиотека
То, что вы описали - попытка реализовать связь: ВашаComБиблиотека -> СтороняяБиблиотека
Осталось реализовать связь между 1C и вашей библиотекой. Чтобы начать разработку библиотеки по технологии COM в Delphi нужно выбрать: File -> New -> Other и там найти ActiveX Library, новый проект будет выглядить приблизительно так:
Далее к проекту добавить COM-сервер: File -> New -> Other и найти COM Object, выглядеть в новых версиях Delphi будет как-то так:
В старых версиях Delphi так:
В полях ClassName (CoClassName) нужно ввести английское название, по которому 1C и будет загружать вашу библиотеку после регистрации в системе, например: MaximLibrary1C Подробнее о пошаговом создании COM-библиотеки можете почитать здесь: http://www.introligator.org/articles/3/78 После написания прослойки (куда вы перенесете свой вышеописанный код) и окончания разработки на целевой машине вашу новую .dll нужно зарегистрировать в системе, как-то так: regsvr32 c:\Library\Project1.dll Конечно, имя проекта лучше задать более вменяемое, а не Project1.
На машине с Delphi зарегистрировать можно из среды в меню "Run".
Из самой 1C вашу библиотеку после регистрации в системе можно будет загружать как-то так: МояБиблиотека = Новый COMОбъект("MaximLibrary1C");
// вызываем метод в библиотеке
МояБиблиотека.1C_ProcessBonusListCountersPrint();
Углубляю познания о джаве. Наткнулся на статью о типах ссылок. Понял, что существуют 4 типа ссылок:
Strong reference
Weak Reference
Soft Reference
Phantom Reference
Незнаю, правильно ли я понял, поэтому прошу подправить. 1 Тип сильная ссылка (Strong reference) Object object = new Object();//создал обьект
object = null;//теперь может быть собран сборщиком мусора
2 Тип слабая ссылка (Weak Reference) // какой-то объект
Object object= new Object (); // слабая ссылка на него
WeakReference