Страницы

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

вторник, 23 апреля 2019 г.

Как проще всего сымитировать репозиторий (данные)

У меня есть интерфейс репозитория, например:
public interface IUserRepository { IEnumerable ListUsers(); User GetUserById(int id); void AddUser(User user); void DeleteUser(User user); void EditUser(User user); }
где User, например, выглядит так:
public class User { public int Id { get; set; } public string Name { get; set; } public IEnumerable { get; set; } public string Email { get; set; } }
на всякий случай,
public class Role { public int Id { get; set; } public string Name { get; set; } }
Как проще всего сделать имитацию данного репозитория с фейковыми данными?
Если просто сделать singleton внутри которого определить List, то это меня смущает, потому что будут отличия в поведении от реального репозитория. Если в реальном репозиторие два раза сделать GetUser(id) (с одним и тем же id), то получим два экземпляра объекта. А если в singleton-е или статическом классе так же будем 2 раза доставать из List<>, то получаем один экземпляр объекта. Если делать Text File или XML, то вроде как долго. Хотелось бы максимально простой вариант найти. Но если это самый простой вариант, то скажите, тогда сам отвечу, что получилось. Что касается SQLite, то тем более городить долго, не стоит того. Если использовать Моки, то смущает, что у меня почти нет с ними опыта работы, и то, что данные (например, имя, Email) будут выглядеть не красиво. Кажется, в моей ситуации проще самому ввести как-то данные для 5-10 пользоватей.
UPDATE: Сохранять состояние достаточно в рамках одного сеанса работы программы. После ее выключения, можно сбрасывать добавленных или измененных User-ов


Ответ

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

Объединение двух массивов в C# (заданное количество элементов)

Есть два массива list1 и list2. При помощи LINQ нужно получить массив list3 состоящий из заданного кол. элементов из list1 и заданного кол. элементов из list2


Ответ

Воспользуйтесь функциями:
Concat(), которая объединяет две последовательности в одну. Take(), которая позволяет вернуть первые N элементов из последовательности
Например
var list1 = new List() { "1", "2", "3", "4", "5", "6", "7" };
var list2 = new List() { "1", "2", "3", "4", "5", "6", "7" };
var list3 = list1.Take(5).Concat(list2.Take(3));
В итоге list3 будет содержать 5 элементов из первого списка, и 3 - из второго
"1", "2", "3", "4", "5", "1", "2", "3"
Если вы хотите из списков брать не первые элементы, а 'элементы где-нибудь из середины списка, то тогда вам в помощь функция Skip(), которая позволяет пропустить N количество элементов с начала последовательности
var list3 = list1.Skip(2).Take(5).Concat(list2.Take(3));
Результат в list3
"3", "4", "5", "6", "7", "1", "2", "3"

Выделение текущего выбранного файла в папках проекта в sublime?

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


Ответ

Нажмите правой кнопкой мыши в основной области, и в контекстном меню выберите пункт Reveal in Side Bar, текущий файл будет подсвечен в дереве файлов и каталогов.

VBA и SQL. Разделение таблицы

Имеется таблица с полями a, b, c, d. Тип полей заранее неизвестен. Необходимо создать новую таблицу и скопировать туда поле с и соединить его с полем с в исходной таблице.
Среда программирования: MS VBA 7.1
СУБД: Microsoft Access 2013


Ответ

Проще сделать так:
SELECT c Into new_table from Old_table;
Таблица создается на лету.

как правильно переопределить метод SetValueAt()?

при переопределении данного метода выдается ошибка:
The left-hand side of an assignment must be a variable.
Как ее убрать?
Фрагмент кода программы :
public class AbstrTableModel extends AbstractTableModel {
HashMap hashMap; public static int key = 0; private File fin; private Scanner fileScanner;
public AbstrTableModel(){ AbstrTableModel.key = 0; hashMap = new HashMap(); }
//-------------------------------------
@Override public void setValueAt(Object value, int rowIndex, int columnIndex){ switch(columnIndex){ case 1: hashMap.get(rowIndex).setModel() = (String)value; return; case 2: hashMap.get(rowIndex).setRazmer() = (Double)value; return; case 3: hashMap.get(rowIndex).setTip_displeya()= (String)value; return; case 4: hashMap.get(rowIndex).setVmFlash()= (Integer)value; return; } } }


Ответ

Ошибка значит - "в левой части оператора присваивания должна быть переменная".
Вы не можете использовать конструкцию hashMap.get(rowIndex).setModel() в левой части операции присваивания. Если setModel() -метод-сеттер, то он и должен устанавливать какое то значение через свой аргумент.

Многопоточность для обработки файла

Есть много огромныйх файлов(по 4-6gb), мне нужно запустить примерно 100 потоков, чтобы каждый поток брал следующую строку из файла и обрабатывал.
List _threads; int countThr;
public void Run(int count) { Globals.threadAlive = 0; _threads = new List(); _threads.Clear(); countThr = count; for (int i = 0; i < count; i++) { var thread = new Thread(multiThread); thread.IsBackground = true; _threads.Add(thread); _threads[i].Start(); } }
public void Abort() { Globals.threadAlive = 1; foreach (Thread thr in _threads) { thr.Abort(); } _threads.Clear(); Globals.threadAlive = 0; }
private void multiThread() { for (int c = 0; c < Globals.lines.Length; c++) { //обработка строки } Globals.threadAlive = 1; Abort(); }
Это будет правильное решение моей задачи?


Ответ

Я предлагаю вычитывать с помощью File.ReadLines, это позволяет не загружать весь файл в память.
Разбирать отдельные строки в отдельных задачах для потоков - нерентабельно, скорее всего, зависит от того, как долго занимает обработка одной строки.
Поэтому предложенный вариант разбивает все строки на пакеты небольшого размера (batches) и обрабатывает их параллельно.
void Main() { var filePath = Path.GetTempFileName(); File.WriteAllText(filePath, string.Join(Environment.NewLine, Enumerable.Range(0, 100001)));
var batchSize = 1000;
var allLines = File.ReadLines(filePath);
var processedCount = 0;
GetLinesInBatches(allLines, batchSize).AsParallel().ForAll(batch => { foreach (var line in batch) { Interlocked.Increment(ref processedCount); // Do something with the line. } });
Console.WriteLine("Total: {0}", processedCount); }
IEnumerable> GetLinesInBatches(IEnumerable allLines, int batchSize) { using (var e = allLines.GetEnumerator()) { bool more = false; do { var batch = new List(batchSize); for (var i = 0; i < batchSize && (more = e.MoveNext()); i++) { batch.Add(e.Current); } yield return batch; } while (more); } }

Скалярное произведение векторов, SSE

Помогите с примером скалярного произведения двух векторов, заданных массивами типа double, при помощи SSE инструкций. Все найденные мной примеры почему-то написаны для типа float Например, вот такая функция
float inner(int n, float* x, float* y) { __m128 *xx = (__m128*)x; __m128 *yy = (__m128*)y; __m128 s = _mm_setzero_ps();
for(int i=0; i

Ответ

А здесь ничего сложного нет. Просто нужно поменять команды на другие. Double вдвое больше по размеру, чем float, поэтому цикл нужно вести до n/2, а не до n/4, далее, ищите справочник и команды работы с double. Например, _mm_mul_pd - это умножение double, аналогично, скорее всего, _mm_add_pd будет для сложения. Аналогично можно отыскать в гугле остальные команды, у меня на это ушло 5 минут.
UPD: лучше после цикла не делать эту ерунду, что написана в примере, а лучше командой _mm_store_pd сохранить два double из xmm регистра в две переменные и спокойно вернуть их сумму.