Страницы

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

четверг, 27 февраля 2020 г.

Использование BufferedReader в Java

#java


Изучаю Java. В литературе и на многих ресурсах пишется, что использование буферезированного
ввода данных является наиболее эффективным, с точки зрения производительности. Но нигде
не говорится, за счет чего достигается эта эффективность. 

Может кто нибудь просвятить по этому вопросу?  
    


Ответы

Ответ 1



Когда вы используете BufferedReader, вы делаете меньше запросов к нижележащему Reader, а он в свою очередь делает меньше запросов к InputStream. К примеру, вы считываете файл посимвольно. Для каждого символа ваш Reader будет вызывать метод read на FileInputStream, а он в свою очередь будет вызывать низкоуровневую функцию операционной системы, которая запросит информацию в драйвера, а он запустит перемещение головки жёсткого диска и непосредственно само чтение. И так для каждого символа. Но если вы используете BufferedReader, то он сразу считает 8кб (дефолтный размер буффера) в память, и дальше посимвольное чтение не будет вызывать длинную цепочку вызовов вплоть до физического чтения с диска. Естественно, если вы считываете данные большими кусками, то BufferedReader никак не ускорит это. На самом деле все гораздо сложнее, ведь ОС или драйвер сами могут буфферизировать прочитанные данные, но вы не можете знать наверняка, как работает конкретный InputStream, и есть ли в него какой-то внутренний буффер.

Создание хранилища объектов

#c_sharp #память


Товарищи, встал перед такой проблемой:

Мне необходимо реализовать нечто вроде хранилища объектов, которое бы выдавало по
одному экземпляру указанного объекта на пользователя

Попробую пояснить с помощью псевдокода:

// Добавим в хранилище правило создания объекта 
storage.Add("tmp", () => new Foo()); 

{
    // В хранилище пока нет сгенерированных объектов
    // Так что создаётся новый, сохраняется и возвращается 
    Foo tmp0 = storage["tmp"];
}

// Здесь ссылка на tmp0 уже недействительна 
// Так что единственная ссылка на тот созданный объект лежит внутри хранилища 
// Возвращаем тот же объект, что был в tmp0
Foo tmp1 = storage["tmp"];

// Тот объект, что был создан для tmp0, а теперь хранится в tmp1, уже занят 
// Так что создаём новый объект, сохраняем его в хранилище и его же и возвращаем 
Foo tmp2 = storage["tmp"];


То есть при завершении области видимости для tmp0 хранилище, содержащее в себе ссылку
на тот же объект, его не удаляет, а сохраняет до следующего запроса подобного объекта. 

То есть логика такая:


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


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

Вроде как нигде нет «счётчика» ссылок на объекты, так как сборщику мусора плевать,
сколько там раз была объявлена ссылка на определённый объект. Важно лишь то, есть ли
таковая ссылка вообще

Так что даже не знаю, возможно ли вообще реализовать подобное средствами C#...



UPD:

Я никак не могу выбрать, какой ответ пометить галочкой, ибо ответы от iluxa1810 и
default locale  являются более правильными для общего случая. Однако в рамках моей
весьма специфичной задачи более подходит метод, описанный в ответе от John... 
    


Ответы

Ответ 1



Можно вывернуться, создав класс-обертку. Я постараюсь вкратце сейчас, потому что с телефона. Суть в том, что мы используем финализатор обертки, чтобы отловить событие удаления обертки и вернуть наш экземпляр в строй. Создаём наш класс-обертку: class FooWrapper { public event Action Final; private Foo foo; private int id; public FooWrapper(Foo foo, int id) { this.foo = foo; this.id = id; } // Вот и наш финализатор ~FooWrapper() { if (Final != null) Final(id) } } В самой программе создаём два словаря. Один - для неиспользуемых экземпляров foo, а второй - для используемых. Думаю, логика более или менее понятна? 1) по требованию пользователя ищется в словарях экземпляр Foo. В данном случае по Id. 2) если нет, то создаётся Foo и помещается во второй словарь. Его мы передаём в FooWrapper и обязательно подписываемся на событие Final. Полученный FooWrapper уже отдаем пользователю. 3) после того, как у пользователя пропадают все ссылки на FooWrapper срабатывает финализатор, в котором срабатывает событие Final, передающее ID нашего Foo. 4) В основной программе мы получаем этот Id и переносим из второго словаря в первый. Главный недостаток, что в данном случае мы полностью исключает возможность взаимодействия напрямую с foo, только через методы, который в fooWrapper пропишешь.

Ответ 2



Вот тут похожий вопрос и там предоставляется решение в виде использования WeakReference -это такая ссылка на объект, которая не препятствует сборки мусора. У него есть свойство IsAlive, которое говорит жив ли объект или уже был собран сборщиком мусора. Мне видится, что это вы можете задействовать в своей задаче. В вашем случае, объект будет жив до тех пор, пока кто-то на него ссылается из кода. Проверить, есть ли ссылка на объект в коде нельзя. .NET ушли от подсчета кол-ва ссылок на объект в пользу построения графа доступности объектов. Как альтернативный вариант- это ввести внутри вашего хранилища подсчет, заставляя пользователя вызывать спец. метод. Но тут все строится на доверии... Например, вдруг забудут что-либо вызвать => объект будет зарегистрирован за кем-то.

Ответ 3



Возможно, в Net найдется механизм, который решит задачу, в том виде, в каком Вы ее написали. Но, если честно, мне это решение кажется неочевидным и хрупким: неочевидным, т.к. конец блока кода легко пропустить при чтении, и, поэтому, редко используется для критичных операций: } //за одним символом здесь кроется важная операция по освобождению объекта. Как разработчик, я ожидаю, что блоки кода можно свободно переставлять при рефакторинге. В данном случае при этом нужно будет очень внимательно отследить срок жизни всех переменных. Ситуация усложнится если ссылки на Foo будут сохраняться в полях других классов (объекты которых сами будут храниться в коллекциях и захватываться в лямбдах). хрупким, т.к. в данном случае логика будет сильно зависеть от работы сборщика кода, которую сложно контролировать. Альтернатива: объектный пул Для решения Вашей проблемы (дорогостоящие объекты, которые желательно переиспользовать) подойдет шаблон проектирования «объектный пул». Пулы широко используются для схожих задач (хранения соединений к БД, например). В простейшем варианте Вам достаточно: Реализовать для Foo интерфейс IDisposable. В storage отслеживать вызов метода Dispose для созданных Foo и освобождать объекты. В вызывающем коде всегда оборачивать полученные из storage объекты в блок using Для чистоты эксперимента можно вынести методы/свойства Foo в отдельный интерфейс, который и возвращать из storage. Реализацию Foo оставить доступной только для storage, чтобы никто не мог переопределить методы. Решение скучное и предполагает изменение вызывающего кода. Зато в данном варианте процесс освобождения объектов становится очевидным. Ну и код будет выглядеть примерно так: using(var tmp0 = fooPool.GetFoo("tmp")) { //работаем с одним объектом } using(var tmp1 = fooPool.GetFoo("tmp")) { using(var tmp2 = fooPool.GetFoo("tmp")) { //работаем с двумя объектами } }

Как работает SqlBulkCopy в .NET “за кулисами”?

#net #sql_server


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

Билдер команды нашел, но, вроде, в нем нет ничего сверхъестественного.

Нашел, где данные хранятся перед отправкой - независимо от того, что подается на
вход, они копируются в массив, но самого интересного не нашел...
    


Ответы

Ответ 1



Общение клиентских приложений с SqlServer происходит посредством протокола TDS (Tabular Data Stream Protocol), спецификацию которого можно найти здесь. При bulk-загрузке клиент посылает серверу сообщение типа Bulk Load (раздел 2.2.1.5 спецификации): 2.2.1.5 Bulk Load ... The client sends the INSERT BULK SQL statement and then sends a COLMETADATA token that describes the raw data. Multiple rows of binary data are then sent to the server. ... т.е. серверу передаются (последовательно) INSERT BULK команда (специальная разновидность INSERT, не путать с BULK INSERT) метаданные столбцов передаваемых данных собственно сами строки данных Если сообщение длинное (например, текст команды длинный, или данных много, что типично для bulk-загрузки), то оно передаётся несколькими пакетами. Для осуществления взаимодействия посредством TDS-протокола SqlBulkCopy использует вспомогательный класс TdsParser. Вообще TdsParser (вместе с TdsParserStateObject) является одним из краеугольных классов во внутренней инфраструктуре System.Data.SqlClient (и используется также такими классами как, например, SqlCommand, SqlDataReader, SqlConnection). Последовательность от вызова метода WriteToServer (WriteToServerAsync) до отправки данных на сервер примерно такая: WriteToServer WriteRowSourceToServerAsync WriteToServerInternalAsync ReadFromRowSourceAsync WriteToServerInternalRestAsync CreateAndExecuteInitialQueryAsync CreateInitialQuery WriteToServerInternalRestContinuedAsync AnalyzeTargetAndCreateUpdateBulkCommand CopyBatchesAsync SubmitUpdateBulkCommand CopyBatchesAsyncContinued WriteMetaData CopyRowsAsync CopyColumnsAsync ReadWriteColumnValueAsync GetValueFromSourceRow TdsParser.WriteBulkCopyValue Из этого наиболее интересно следующее. Метод CreateInitialQuery формирует команду SET FMTONLY ON select * from [TableName] SET FMTONLY OFF которая используется для получения информации о столбцах целевой таблицы. Метод AnalyzeTargetAndCreateUpdateBulkCommand формирует INSERT BULK команду наподобие, например, такой insert bulk [TableName] ([Id] int) with (TABLOCK) Метод SubmitUpdateBulkCommand передаёт сформированный текст команды на сервер. Метод WriteMetaData передаёт метаданные столбцов. В этом методе, что интересно, перед передачей метаданных есть строка кода _stateObj._outputMessageType = TdsEnums.MT_BULK; (префикс MT_ означает message type). Это значит, что передача Bulk load сообщения инициируется здесь, а не с отправки команды INSERT BULK несколько ранее в методе SubmitUpdateBulkCommand. Если вернуться ненадолго в этот метод, то можно найти там вызов TdsExecuteSQLBatch, проследовав внутрь которого, можно обнаружить строку кода stateObj._outputMessageType = TdsEnums.MT_SQL; т.е. текст команды посылается отдельным сообщением. Это несколько неожиданно, т.к. читая раздел 2.2.1.5 спецификации сложилось впечатление, что и текст команды также должен быть частью Bulk load сообщения. Впрочем, в разделе 2.2.6.1 спецификации 2.2.6.1 Bulk Load BCP ... This message sent to the server contains bulk data to be inserted. The client MUST have previously notified the server where this data is to be inserted. For more information about the INSERT BULK syntax, see [MSDN-INSERT]. ... поясняется (недостаточно явно, на мой взгляд), что Bulk load сообщение содержит данные для вставки, а перед его отправкой серверу нужно сообщить куда вставлять данные. Таким образом, bulk-загрузка происходит посредством отправки двух сообщений серверу: INSERT BULK команда (куда вставляем) метаданные столбцов данных + строки данных (что вставляем) Следуем дальше. Метод CopyRowsAsync отвечает за передачу строк данных. Внутри ReadWriteColumnValueAsync происходит вызов метода WriteBulkCopyValue класса TdsParser. Внутри метода WriteBulkCopyValue последовательность вызовов примерно следующая TdsParser.WriteBulkCopyValue TdsParser.WriteValue/WriteSqlValue/WriteShort/WriteInt/WriteLong/WriteDouble/... TdsParserStateObject.WriteByte/WriteByteArray TdsParserStateObject.WritePacket TdsParserStateObject.WriteSni TdsParserStateObject.SNIWritePacket SNINativeMethodWrapper.SNIWritePacket Логика разнообразных вызовов, происходящих внутри WriteBulkCopyValue, заключается в основном в том, что данные (в байтовом представлении) пишутся в буфер, пока он не полон. Когда же буфер (будущий TDS-пакет) заполнился (TDS-пакет готов), происходит его отправка на сервер (метод SNIWritePacket). Внутри SNIWritePacket вызов метода SNINativeMethodWrapper.SNIWritePacket - это обращение ко внешней библиотеке sni.dll, которая обеспечивает взаимодействие с транспортным уровнем (Shared Memory, Named Pipes, TCP).

Ответ 2



SqlBulkCopy использует datatable, IDataReader или DataRow[] в качестве источника данных. Обратите внимание на SqlBulkCopy.WriteToServer если хотите больше подробностей. А также на The Data Loading Performance Guide, там рассматриватся BCP, но информация о BulkCopy также представлена.

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

#python #массивы #numpy


У меня есть такой numpy-массив:

Y =  [[0.9]
 [0.1]
 [0.1]
 [0.9]
 [0.1]]


Мне нужно, чтобы print(Y) выводил на печать просто строкой все значения. Вот так:

 0.9, 0.1, 0.1, 0.9, 0.1


Сейчас он выводится столбиком. Как это сделать с массивом numpy?
    


Ответы

Ответ 1



Я так понял, вам нужно вывести без скобок и с разделением по запятым: import numpy arr = numpy.array([[0.9], [0.1], [0.1], [0.9], [0.1]]) print(arr) # [[0.9] # [0.1] # [0.1] # [0.9] # [0.1]] print(', '.join(map(str, arr.ravel()))) # 0.9, 0.1, 0.1, 0.9, 0.1

Ответ 2



Можно например, использовать метод ravel: > print(Y.ravel()) [0.9 0.1 0.1 0.9 0.1]

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

#delphi


У меня по большей части - обработка текстовой информации, чтение, запись.

По умолчанию, в настройках проекта стоят такие размеры:

Maximum Stack Size - 1048576
Minimum Stack Size - 16384


Если изменения влияют на скорость то какие параметры - должны быть (в большую или
меньшую сторону). И что от чего зависит ? 
    


Ответы

Ответ 1



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

Для чего нужны события и слушатели событий в Laravel на примере интернет-магазина?

#php #laravel #события


Использую laravel 5.6 для разработки интернет-магазина и как-то не приходилось пользоваться
событиями и их слушателями. Не пойму, для чего они нужны и как могут упростить разработку.
В официально документации все написано как, а почему и зачем нет информации. Если можно,
приведите на конкретном примере интернет-магазина, где там можно использовать эту фишку.
    


Ответы

Ответ 1



Если очень кратко и в двух словах, то: События и слушатели - это реализация паттерна Observer (статья на Википедии). Смысл в том, что у вас есть класс, в нем есть функции, вот вы хотите чтобы при вызове функций этого класса, вызывалась функция из другого класса - Вот собсна для чего и нужно. Функция из первого класса - будет событием (а точнее её вызов) Функция из второго класса - будет эвентом. Вы можете подумать - что мне мешает вызвать из одной функции другую, без этих слушателей. Но это будет не совсем правильно. Давайте на пальцах: Самый банальный пример: пусть у нас есть класс Users, у этого класса есть метод Auth (авторизация). Т.е. этот метод отвечает за логику-авторизации, и вызывается он только тогда когда происходит успешный вход (ввод логина и пароля). Теперь мы хотим, чтобы при входе, нам приходило письмо, что кто-то на нашем сайте вошел в систему. У нас, условно, есть класс Admin и у него метод SendMessage, который реализует данную логику. Самое первое что может прийти на ум, мы внутри метода Auth можем написать вызов класса Admin и его метода SendMessage. Но это будет не правильно, потому что в логике Auth внутри появляется сторонняя логика SendMessage (P.S. вот тут очень тонко, сложно для понимания, где логика считается раздельной, а где единой, но думаю вы понимаете). Правильней применить наш паттерн, и реализовать такую систему, где при вызове Auth вызовется наш SendMessage, не влияя на логику внутри Auth. Почему я сказал про тонкость? Дело в том, что где-то SendMessage будет являться частью логики Auth и тогда вызов внутри функции - это нормально, а где-то нет. Для визуального представления различий ситуации, давайте возьмем третий класс Logs с методом CreateLog - цель которого записывать(логировать) какие-то данные о нашем пользователе. Понятное дело что логировать надо не только Auth, а еще и вход, и выход, и регистрацию, и восстановление - а это все функции, если мы в каждой функции будем дописывать вызов нашего класса Logs и метода CreateLog - то как видите получится не совсем красиво, потом после отладки забудем где-то что-то удалить, или забудем где мы что писали, ходи по файликам и ищи. Собсна в такой ситуации с логированием, лучшего помощника, чем слушатель - не найти. Мы просто указываем какие функции нам нужны (события), и какую функцию вызывать. P.S. Это мое личное представление, может быть искажено с реальным представлением о паттерне Observer. При написании ответа ни один класс и метод не пострадал!

Ответ 2



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

Ответ 3



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

Ошибка при сохранении данных в БД

#c_sharp #sql_server


При сохранении данных в БД возникает ошибка:


  Существует назначенный этой команде Command открытый DataReader,
  который требуется предварительно закрыть


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

public bool UpdateSettings(Guid settingsId, List usersModel)
{
    using (var connection = new SqlConnection(_connectionString))
    {
        connection.Open();

        try
        {
            using (var command = connection.CreateCommand())
            {
                command.CommandText = "DELETE FROM UsersSettings WHERE SettingsId
= @SettingsId";
                command.Parameters.AddWithValue("@SettingsId", settingsId);
                command.ExecuteReader();
            }

            foreach (var userModel in usersModel)
            {
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = @"INSERT UsersSettings(SettingsId, SettingsValue,
IsEnabled)
                                            VALUES (@SettingsId, @SettingsValue, 1)";
                    command.Parameters.AddWithValue("@SettingsId", settingsId);
                    command.Parameters.AddWithValue("@SettingsValue", userModel.SettingsValue);
                    command.ExecuteReader();  // Ошибка возникает в данной строке
                }
            }

            return true;
        }
        catch (Exception exception)
        {
            _log.LogError("Не удалось сохранить настройки.", exception);
            return false;
        }
    }
}

    


Ответы

Ответ 1



Reader, который возвращает ExecuteReader, нужно вручную закрывать. Если не используете результат запроса, вызывайте ExecuteNonQuery.

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

#javascript #vuejs


Написал тренировочный Vue компонент с шаблоном. В шаблоне использовал шаблонные литералы
и возникла проблема с подстановкой url адреса до изображения. 
Перепробовал разные варианты, но решить проблему так и не смог.

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






let queryComments = [{
    comment_id: 1,
    comment_image: '//loremflickr.com/100/100',
    comment_description: 'Looks great Julianne!',
  },
  {
    comment_id: 2,
    comment_image: '//loremflickr.com/100/100',
    comment_description: 'I love the sea',
  },
  {
    comment_id: 3,
    comment_image: '//loremflickr.com/100/100',
    comment_description: 'Where are you at?',
  }
];

Vue.component('template_comment', {
  props: ['comment'],
  template: `
  • id: {{comment.comment_id}}
    Комментарий: {{comment.comment_description}}
  • ` }); new Vue({ el: '#comments', data: { comments: queryComments }, });


    Ответы

    Ответ 1



    Vue.JS позволяет привязать данные из javascript к шаблону при помощи директивы v-bind:src или его сокращенной версии :src. В вашем случае необходимо использовать следующую запись:

    Ответ 2



    Если какие-то данные должны подставляться динамически, то вы должны использовать стандартный атрибут, но с двоеточием в начале: let queryComments = [{ comment_id: 1, comment_image: '//loremflickr.com/100/100', comment_description: 'Looks great Julianne!', }, { comment_id: 2, comment_image: '//loremflickr.com/100/100', comment_description: 'I love the sea', }, { comment_id: 3, comment_image: '//loremflickr.com/100/100', comment_description: 'Where are you at?', } ]; Vue.component('template_comment', { props: ['comment'], template: `
  • id: {{comment.comment_id}}
    Комментарий: {{comment.comment_description}}
  • ` }); new Vue({ el: '#comments', data: { comments: queryComments }, });


    Что в Java является константой, а что - нет?

    #java #переменные #интерфейс #константа

    
    До недавнего времени я был почти на 100% убеждён в том, что прекрасно понимаю сущность
    констант в языке программирования Java. Так было, пока я не наткнулся на один из примеров,
    который был представлен в JLS (Java Language Specification). Он немного поверг меня
    в ступор, и я не могу разобраться с этим вопросом вплоть до текущего момента.
    
    Наверное, я не сильно ошибусь, если скажу, что типичных констант в языке программирования
    Java нет вообще (во всяком случае, если смотреть с колокольни какого-нибудь С++). Даже
    ключевое слово const, которое зарезервировано с незапамятных времён, но до сих пор
    не используется, как бы ненавязчиво намекает нам об этом (не уверен, но вроде бы это
    было сделано для того, чтобы сохранить обратную совместимость с С++ в том случае, если
    константы всё-таки будут введены в язык).
    
    В качестве некоторого общепринятого суррогата используется связка модификаторов static
    final в процессе декларирования переменной. Если я правильно понимаю, то именно такие
    переменные и считаются константами с точки зрения программистского сообщества ЯП Java.
    В то же время, если заглянуть на просторах JLS в параграф, который посвящён инициализации
    классов и интерфейсов, мы можем наткнуться на один интересный момент. Небольшая выдержка
    оттуда:
    
    
      Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces
    
    
    interface I {
        int i = 1, ii = Test.out("ii", 2);
    }
    interface J extends I {
        int j = Test.out("j", 3), jj = Test.out("jj", 4);
    }
    interface K extends J {
        int k = Test.out("k", 5);
    }
    class Test {
        public static void main(String[] args) {
            System.out.println(J.i);
            System.out.println(K.j);
        }
        static int out(String s, int i) {
            System.out.println(s + "=" + i);
            return i;
        }
    }
    
    
    
      This program produces the output:
      
      1
      j=3
      jj=4
      3 
      
      The reference to J.i is to a field that is a constant
      variable (§4.12.4); therefore, it does not cause I to be initialized
      (§13.4.9).
      
      The reference to K.j is a reference to a field actually declared in
      interface J that is not a constant variable; this causes
      initialization of the fields of interface J, but not those of its
      superinterface I, nor those of interface K.
      
      Despite the fact that the name K is used to refer to field j of
      interface J, interface K is not initialized.
    
    
    И вот этот момент мне совершенно непонятен! В интерфейсах все поля неявным образом
    помечаются как public static final (другими они и не могут быть), что мы и видим в
    приведённом примере. Все поля имеют совершенно одинаковый набор модификаторов, но при
    этом, поле J.i называют константной переменной, а K.j константой уже не является, если
    верить примеру, который приведён в JLS.
    
    Что же такое константа с точки зрения JLS? Неужели это не абсолютно все статические
    финализированные поля? Правильно ли я понял, что при присваивании значения через его
    возврат функцией, мы уже не можем считать поле константой?
        
    


    Ответы

    Ответ 1



    С точки зрения JLS: A constant variable is a final variable of primitive type or type String that is initialized with a constant expression То есть константа - это final переменная (причем речь не только о static и не только о полях) примитивного типа или типа String, которая проинициализирована константным выражением Вызов метода константным выражением не является, поэтому K.j - это не константа

    Сложение volatile - UB?

    #cpp #volatile

    
    Содержит ли следующая программа UB?
    
    #include 
    
    volatile int x;
    
    int main() {
      std::cout << (x + x);
    }
    
        
    


    Ответы

    Ответ 1



    Да, содержит. Несколько доступов к одному и тому же volatile объекту без упорядочения этих доступов (unsequenced access) - неопределенное поведение. Доступ к volatile объектам испокон веков является частью наблюдаемого поведения (observable behavior) С++ программы. Поэтому доступ к volatile объекту (даже только на чтение) формально считается побочным эффектом (side effect) содержащего этот доступ выражения. А далее уже работает общая схема: наличие в выражении неупорядоченных побочных эффектов, воздействующих на один и тот же объект - это неопределенное поведение. [n4659] 4.6 Program execution [intro.execution] 14 Reading an object designated by a volatile glvalue (6.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.[...] 17 [...]If a side effect on a memory location (4.4) is unsequenced relative to either another side effect on the same memory location or a value computation using the value of any object in the same memory location, and they are not potentially concurrent (4.7), the behavior is undefined.[...] В новой структуре документа: http://eel.is/c++draft/basic.exec#intro.execution-7 http://eel.is/c++draft/basic.exec#intro.execution-10

    Как отлавливать строку со сканера штрих-кодов?

    #c_sharp #wpf #штрихкод

    
    Есть сканер штрих-кодов Winson WNL-5000g-USB. Необходимо реализовать приложение на
    C#(WPF) в котором в список будет добавляться строки считанные сканером.
    
    Я никогда такого не делал и не имею малейшего понятия как заставить свое приложение
    отлавливать сканер в нужный момент и показывать считанный штрих-код. Как отлавливать
    строку которую считывает сканер?
        
    


    Ответы

    Ответ 1



    Все оказалось очень просто. Данный сканер определяется на компьютере как клавиатура. Я разместил обычный TextBox, поставил в него указатель мышки и поднес к сканеру штрих-код. Тут же в TextBox'е появился расшифрованный штрих-код. После небольших манипуляций выяснил что после того как сканер сканирует штрих-код, он пишет данные в поле ввода где установлен указатель и автоматический нажимает клавишу "Enter". А дальше дело техники: Наводим указатель на TextBox. Сканируем штрих-код. Добавляем в поле TextBox определение клавиши "Enter". Теперь после того как штрих-код был отсканирован, автоматический вызывается команда которая добавляет штрих-код в список. Обновляем список и видим в нем наш штрих-код.

    Ответ 2



    Диплом в прошлом году писал и как раз использовал их в работе. У сканеров есть три типа подключения: RS-232 Данные будут передаваться в последовательный порт в виде ASCII-символов. Смотрим как работать с COM портами. USB-COM (USB-RS) Два варианта: эмуляция RS-232 или передача в порт ASCII-символов (тут зависит от производителя). Нужны будут дрова или api. USB (разрыв клавиатуры) или PS/2 Просто имитирует нажатие клавиш на клавиатуре. Ставим фокус на форму ввода сканируем и код будет в строке. Обращу внимание, что результат может зависеть от раскладки клавиатуры.

    Как заменить повторяющиеся группы элементов с помощью replaceAll?

    #java #строки

    
    Вопрос относительно метода replaceAll в String.
    
    Допустим, есть строка, содержащая строковое представление xml, где повторяются элементы:
    
    
     
      Alex
      Gazprom
     
     
      Irina
      Lukoil
     
    .*", "Rosneft");
    
    
    То получится так:
    
    
     
      Alex
      Rosneft
     
    


    Ответы

    Ответ 1



    Для отключения "жадности" поиска используется квантификатор ?: line.replaceAll(".*?", "Rosneft"); Описание работы квантификаторов, например, есть здесь и здесь

    распространение программ под лицензией GNU GPL

    #лицензирование

    
    когда программа распространяется под лицензией, допустим (с потолка пример 
     лицензия РРС) это выходит что разработчик после релиза программы, обратился в специальную
    организацию и залицензировал её? или просто написал что распространяю вот так и все!
        
    


    Ответы

    Ответ 1



    Как применять лицензии GNU со своими программами Вот краткая сводка того, что вам нужно сделать, чтобы выпустить программу под одной из наших лицензий: Получить отказ от авторских прав у своего работодателя или учебного заведения. Присоединить к каждому файлу соответствующие уведомления об авторских правах. Не забывайте ясно указывать, какие версии лицензии могут применять пользователи. Добавить файл COPYING с копией GNU GPL или GNU AGPL. Добавить также файл COPYING.LESSER с копией GNU LGPL, если вы применяете ее. Поместить в каждый файл уведомление о лицензии. (По желанию) сделать так, чтобы программа отображала уведомление в начале работы. (Если применяется AGPL) сделать так, чтобы программа предлагала копии своего исходного текста. Процедура включает в себя добавление двух элементов в каждый файл исходного текста вашей программы: замечание об авторских правах (например, “Copyright 1999 Терри Джонс”) и заявление о разрешении копирования, в котором сказано, что программа распространяется на условиях Стандартной общественной лицензии GNU (или Меньшей GPL, или GPL Афферо).

    @value( ${} ) в spring не работает

    #java #xml #spring

    
    Пишу приложение на java с использованием Spring. Нужно передать значение ключа из
    файла app.properties в поле класса. Передает null. Выскакивает NullPointerException,
    уже не знаю что и делать, помогите кто чем может
    
    конфигурация spring:
    
    
    
    
    
    
        
    
    
    
    файл properties:
    
    price=^[1-9][0-9.]{0,10}
    
    
    в классе:
    
    import org.springframework.beans.factory.annotation.Value;
    ....
    @Value("${price}")
    private String price;
    private Pattern PRICE_REGEX = Pattern.compile(price);
    
        
    


    Ответы

    Ответ 1



    @Value("${price}") в твоём случае работает. Другое дело, что ты вызываешь private Pattern PRICE_REGEX = Pattern.compile(price); до того, как отработает @Value. Тебе надо перенести логику инициализации PRICE_REGEX в post-конструктор. На выходе должно получиться примерно так: import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.regex.Pattern; @Component public class Question909652 implements InitializingBean { @Value("${price}") private String price; private Pattern PRICE_REGEX; @Override public void afterPropertiesSet() throws Exception { PRICE_REGEX = Pattern.compile(price); } } Ну или можно похитрить и использовать всю мощь SpEL import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.regex.Pattern; @Component public class Question909652 { @Value("#{T(java.util.regex.Pattern).compile('${price}')}") private Pattern PRICE_REGEX; } P.S. Как правильно заметил @Qwertiy, у тебя очень странное регулярное выражение для цены, быть может тебе больше подойдёт [0-9]*([.][0-9]{1,2})?

    Ответ 2



    Добавь аннотацию @PropertySource("classpath:app.properties").

    Как обернуть вызов сервисов из рест-контроллера для отлова исключений?

    #java #spring #jpa

    
    Есть рест - сервис на spring:
    
    @RestController
    public class UserController {
        @Autowired
        private UserService service;
    
        @RequestMapping(value = "/users", method = RequestMethod.POST)
        public Users add(@RequestBody Users users,
                                  @RequestParam(value = "id", required = false) String id) {
            return service.add(id, users.getUsers());
        }
    
        @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
        public @ResponseBody Users findById(@PathVariable(value = "id") String id) throws
    Exception {
            return service.find(id);
        }
    }
    
    
    Который обменивается с клиентом с использованием xml и jaxb. При этом сущность Users
    выглядит следующим образом:
    
    @XmlRootElement(name = "Users")
    @NoArgsConstructor
    @AllArgsConstructor
    @XmlAccessorType(XmlAccessType.FIELD)
    @Getter
    @Setter
    public class Users {
        @XmlElement(name = "users")
        private List Users;
    
        @XmlElement(name="UserError")
        private UserError error;
    
        public void appendUsers(Users Users){
            if (Users == null) return;
    
            if (Users.getError() != null){
                this.error = Users.getError();
            }
    
            if ( Users.getUsers() != null) {
                if (this.Users == null){
                    this.Users = new ArrayList<>();
                }
                this.Users.addAll(Users.getUsers());
            }
        }
    }
    
    
    То есть, по сути, это два поля, в одном из котором хранится список пользователей,
    в другом - ошибка если возникла.
    
    В процессе выполнения service.add может возникнуть ошибка, например база данных оказалась
    недоступна, и метод вернет exception.
    Решением в лоб является обертка всех вызовов сервисов в try catch и, если возникло
    исключение, запись этой ошибки в Users.error.
    
    Есть ли более элегантное решение?
        
    


    Ответы

    Ответ 1



    Конечно есть. Для того чтобы отловить ошибку, допустим, UserNotFoundException в UserController необходимо добавить метод с аннотацией @ExceptionHandler: @ExceptionHadler(UserNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) @ResponseBody private String handleUserNotFoundException( UserNotFoundException ex) { return "user not found"; } Для того чтобы отловить ошибку, допустим, IllegalArgumentException изо всех RestController-ов необходимо обьявить класс с аннотацией @ControllerAdvice: @ControllerAdvice public class RestExceptionHandler { @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public String handleIllegalArgumentException(...) {...} }

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

    #c_sharp #net #com

    
    Как известно, что бы узнать кол-во доступных видео адаптеров через интерфейс DXGI,
    необходимо вызывать метод EnumAdapters до тех пор, пока данный метод не вернет значение
    DXGI_ERROR_NOT_FOUND. 
    
    Казалось бы, будет перечислять через цикл while:
    
        static void Main(string[] args)
        {
            int result = Manager.CreateDxgiFactory(out IDXGIFactory factory);
    
            if (result != 0)
            {
                Exception erForHr = Marshal.GetExceptionForHR(result);
                throw erForHr;
            }
    
            uint count = 0;
            while (factory.EnumAdapters(count, out _) == 0)
            {
                count++;
            }
            ...
        }
    
    
    Но не тут то было! Как только значение count станет больше чем доступно адаптеров,
    получаем исключение...
    
    
      Объект не найден. При вызове IDXGIFactory::EnumAdaptes отсутствует
      адаптер с указанным порядковым номером. (Исключение из HRESULT:
      0x887A0002)
    
    
    Почему, и как платформа .NET обнаруживает то что произошло исключение, если в коде
    самостоятельно нигде не бросается исключение?
    
    Как отключить данный функционал, т.к. надо перечислять пока есть доступные адаптеры?
    
    Или необходимо оборачивать код в try/catch и в блоке catch выходить из цикла?
        
    


    Ответы

    Ответ 1



    COM Interop по умолчанию преобразует все неуспешные возвращенные HRESULT в исключения. Добавьте атрибут PreserveSig, чтобы это предотвратить: [PreserveSig] int EnumAdapters(...);

    Как работают синглтоны Java?

    #java #android #static

    
    Читая книгу "Программирование под Android" Брайна Харди, я столкнулся со следующим
    кодом. Существует класс синглтон:
    
    public class CrimeLab {
        private static CrimeLab sCrimeLab;
        private Context mAppContext;
    
        public ArrayList mCrimes;
    
        private CrimeLab (Context appContext){
            mAppContext = appContext;
            mCrimes = new ArrayList();
        }
    
        public ArrayList getCrimes() {
            return mCrimes;
        }
    
        public static CrimeLab get(Context c){
            if (sCrimeLab == null){
    
                sCrimeLab = new CrimeLab (c.getApplicationContext());
            }
            return sCrimeLab;
        }
    }
    
    
    Существует ещё один класс, в котором обращаются к методу get и getCrimes класса CrimeLab:
    
    public class CrimeListFragment extends ListFragment {
        private ArrayList mCrimes;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mCrimes = CrimeLab.get(getActivity()).getCrimes();
        }
    }
    
    
    Меня интересует эта строка кода mCrimes = CrimeLab.get(getActivity()).getCrimes();.
    Как мы обращаемся к CrimeLab, если мы не создали экземпляр класса CrimeLab, а статической
    является лишь переменная sCrimeLab в CrimeLab? Могу предположить, что приставка s не
    учитывается, или я сильно не понимаю принцип синглтонов.
        
    


    Ответы

    Ответ 1



    s в данном случае является обозначением статической переменной, но название никак не влияет на её суть, оно может быть любым. Метод get, также является статическим. В коде написано, что если sCrimeLab является null, то необходимо создать экземпляр класса в ином случае вернётся существующий экземпляр. По хорошему можно разделить строку mCrimes = CrimeLab.get(getActivity()).getCrimes(); на CrimeLab crimeLab = CrimeLab.get(getActivity()); mCrimes = crimeLab.getCrimes();

    Как найти закрывающий body и перед ним вставить JS?

    #php

    
    Пытаюсь найти и заменить 
    
    нужно перед  вставить JS, делаю так и получаю ошибку:
    
    syntax error unexpected t_string, expecting ',' or ')'
    
    в строке Varible1: ["Emma", "Noah", "Olivia", "Liam", "Ava","William"],
    
    $response = str_ireplace('', '
    
    
       
    
    ', $response);
    
        
    


    Ответы

    Ответ 1



    Вам надо экранировать одиночные кавычки в скрипте. На первой такой кавычке строка прерывается, и дальнейшее считается кодом. ... $(\'#notification-3\').Notification({ ... и так далее.

    Что такое артефакт (artifact) в контексте языка Java?

    #java #терминология #артефакты

    
    
    
    Что такое артефакт (artifact) в контексте языка Java?
    
    Так же интересно чем Артефакты(Artifacts) отличаются от библиотек(Libraries) в настройках
    проекта.
        
    


    Ответы

    Ответ 1



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

    Ответ 2



    Артефакты - в широком смысле это некие объекты создаваемые в ходе разработки ПО, например схемы классов, объектные коды, документация, инструкции, иконки, картинки и проч. все что сопровождает процесс разработки. В узком смысле - в смысле Intellij IDEA это некая выходная сборка вашего проекта. В общем случае их может быть несколько: jar для десктопа и .war для веба ну и т.д. Для каждого артефакта можно определить правила сборки, развертывания, запуска и т.д. Есть еще артефакты в смысле Maven - это все тот же архив, но предназначенный для деплоймента на репозиторий maven В самом собственно Java нет понятия артефакта - артефакт продукт среды/средства разработки.

    Зачем нужен атрибут scope и его значения “col” и “row”?

    #html #вёрстка #таблицы

    
    Зачем они нужны если при создании таблицы всё работает и без них?
        
    


    Ответы

    Ответ 1



    Атрибут scope связывает между собой ячейки с заголовком и обычные ячейки. По своему действию напоминает атрибут headers, но используется для простых таблиц. Атрибут предназначен для экранных ридеров, вроде речевых браузеров, в обычных браузерах результат добавления scope никак не заметен. Синтаксис: В комментарии @Grundy дал много информации, пройдя по ссылкам, можно найти остальное.

    Алгоритм присваивания отрицательных значений какой-либо переменной в памяти

    #java #операторы #cpu #ram #оператор_присваивания

    
    К примеру, мне известно о том, что все отрицательные числа представляются в памяти
    посредством дополнительного кода. Как это происходит? Русскоязычная терминология немного
    отличается от той, которая была принята на Западе, поэтому было бы правильнее придерживаться
    таких понятий, как первое (обратный код) и второе дополнения, чтобы не нарушать канонов.
    С положительными значениями особых вопросов не возникает, так как прямой, обратный
    и дополнительный код для этих значений абсолютно не отличается. А вот теперь мы и подошли
    к первому вопросу. Меня интересует сам алгоритм присваивания отрицательных значений
    какой-либо переменной. Поскольку я изучаю язык программирования Java, то хотелось бы
    получить ответ именно в данном контексте (хотя я думаю, что для других языков разницы
    также не будет, так как все операции физически осуществляются на уровне микропроцессора).
    Правильно ли я понимаю, что за данное действие отвечает АЛУ (арифметико-логическое
    устройство)? Или же какой-то другой блок процессора?
    
    Здесь мне хотелось бы описать небольшой пример того, как я понимаю алгоритм присваивания
    значения переменной. Допустим, что в нашем абстрактном коде имеется следующая инструкция: 
    
    byte b = -5;
    
    
    Изначально значение записывается в прямом коде, где старший бит является фиксированным
    знаковым битом, который используется для кодирования знака числового значения в знаковых
    типах данных. Получаем следующее двоичное представление: 
    
    1000 0101
    
    
    Затем мы получаем первое дополнение (обратный код). Для этого мы применяем инверсию
    для каждого значащего разряда, которые участвуют в формировании самого числового значения.
    Значение старшего разряда мы оставляем прежним. В результате инвертирования битов получаем
    такой результат:
    
    1111 1010
    
    
    После чего мы добавляем к нашему результату 1, что и является вторым и результирующим
    дополнением. В конечном итоге, в память будет помещено двоичное число, которое соответствует
    числу -5 в десятичной системе счисления: 
    
    1111 1011 
    
    
    Но это всё лишь в моём представлении... Скажите, пожалуйста, насколько я прав? И
    действительно ли обработкой всех этих операций занимается именно АЛУ? Если же я прав,
    то значит ли это, что современные процессоры фактически не используют операцию вычитания
    при арифметических расчётах? 
    
    И еще вопрос, у меня уже давно возникла небольшая путаница с пониманием термина машинное
    слово. В той же Википедии написано, что данная величина зависит от разрядности регистров
    процессора. А от чего в свою очередь зависит эта разрядность? От типа данных в конкретном
    языке программирования? Правильно ли я понимаю, что величина машинного слова типа byte
    в языке программирования Java составляет 8 бит, short и char по 16 бит, а int 32 бита?
        
    


    Ответы

    Ответ 1



    Да, смена знака в дополнительном коде производится инверсией битов и прибавлением единицы. как я понимаю алгоритм присваивания значения переменной Нет, не совсем так. Присваивание byte b = -5; не генерирует арифметических команд, только непосредственно присваивание значения 0xFB (-5). Любые арифметические выражения с константами сворачиваются на этапе компиляции. И действительно ли обработкой всех этих операций занимается именно АЛУ? Да, всей арифметикой занимается АЛУ, кто же еще. За исключением вычислений на этапе компиляции (которые в конечном итоге тоже выполняются АЛУ). значит ли это, что современные процессоры фактически не используют операцию вычитания при арифметических расчётах? Конечно, используют. Хотя вычитание можно выполнять в две команды - инверсия знака + сложение, одна команда вычитания выполняется быстрее. Но вот на уровне микропрограммы процессор может вычитание и не делать. И еще вопрос, у меня уже давно возникла небольшая путаница с пониманием термина машинное слово. В той же Википедии написано, что данная величина зависит от разрядности регистров процессора. А от чего в свою очередь зависит эта разрядность? Разрядность зависит от архитектуры процессора. У 32-разрядных процессоров машинное слово длиной 32 бита. У 64-разрядных соответственно 64 бита. Язык программирования тут не при чем, это аппаратная характеристика процессора.

    Ответ 2



    Главное преимущество дополнительного кода в том что сложение и вычитание работают одинаково как с положительными так и с отрицательными числами. -1 = 1111 1111 1 = 0000 0001 1 + 1 = 0000 0010 -1 + 1 = 0000 0000 -- из-за переполнения. -1 + -1 = 1111 1110

    Как переместить только одну точку из множества в SVG?

    #javascript #html #css #svg #анимация

    
    Пишу SVG + анимация, и столкнулся с такой задачей,-  нужно анимировать только одну
    точку из множества в координатах SVG(чтобы эта точка плавно изменяла свое местоположение
    с привязкой линии от других точек).
    Например: 
    
    d="M10,10 L20,10 L20,20 z" //чтобы плавно переместилась в
    d="M10,10 L123,10 L20,20 z"
    
    
    Как это можно сделать только кодом? Без сторонних программ типа Иллюстратора
        
    


    Ответы

    Ответ 1



    Анимируется атрибут d патча. Подставляется первое значение и финальное положение, через точку с запятой values="M10,10 L20,10 L20,20 z;M10,10 L123,10 L20,20z;M10,10 L20,10 L20,20 z" .container { width:100%; height:100%; }
    Туда, обратно Подставляется в values три значения: стартовое;финальное;стартовое .container { width:100%; height:100%; }
    В атрибут values можно подставить сколько угодно промежуточных значений патча, главное следить, чтобы количество контрольных точек было одинаково у всех промежуточных значений

    CSS - Как размыть маску SVG?

    #css #html5 #svg #анимация #clip_path

    
    Я пытался размыть SVG clip-path.
     Пробовал разные решения, но ни одно не помогло.  
    
    Я не уверен, есть ли другое решение, кроме фильтра.
    
    Pseudocode  
    
    
    SVG clip-path должен раскрывать текст ниже  
    Края, если SVG clip-path применен должны быть размытыми  
    
    
    HTML
    
    
    
        .wrapper {
          display: flex;
          justify-content: center;
          align-items: center;
          position: relative;
        }
        
        .h1, blur {
          width: 100vw;
          height: 100vh;
        }
        
        .h1 {
          position: absolute;
          top: 0;
          left: 0;
          margin: 0;
          padding: 0;
          font-size: 4em;
          clip-path: url(#svgPath);
          background-color: blue;
        }
        
        .blur {
          position: absolute;
          top: 0;
          left: 0;
          margin: 0;
          padding: 0;
          font-size: 4em;
          color: blue;
          background-color: white;
          filter: blur(8px)
        }
    

    Our principles inform everything we do. Whether you're preparing content, designing an interface or developing an entire service, start by reading these.

    Our principles inform everything we do. Whether you're preparing content, designing an interface or developing an entire service, start by reading these.


    Ответы

    Ответ 1



    Хорошо, вот способ сделать это, используя radial-gradient() в качестве mask-image. var h1 = document.getElementById('masked'); document.addEventListener('mousemove', mouseListen, false); function mouseListen(e){ setMaskPos(e.clientX,e.clientY); } function setMaskPos(x,y) { h1.setAttribute("style", "-webkit-mask-image: radial-gradient(circle at " + x + "px " + y + "px, black 0px, black 200px, transparent 250px)"); } // Initialise the mask off screen setMaskPos(-999,0); .wrapper { display: flex; justify-content: center; align-items: center; position: relative; } .h1, blur { width: 100vw; height: 100vh; } .h1 { position: absolute; top: 0; left: 0; margin: 0; padding: 0; font-size: 4em; background-color: white; } .blur { position: absolute; top: 0; left: 0; margin: 0; padding: 0; font-size: 4em; background-color: white; filter: blur(8px) }

    Our principles inform everything we do. Whether you're preparing content, designing an interface or developing an entire service, start by reading these.

    Our principles inform everything we do. Whether you're preparing content, designing an interface or developing an entire service, start by reading these.