Страница 4 из 6
« следующие заметки 1
2
3
4
5
6
предыдущие заметки »
Три дня прошли в улучшениях функциональности сайта и работе над контентом. Эта неделя тоже ожидается ни разу не лёгкой, но постараюсь заниматься блекболычем хотя бы 2 часа в день. Место на харде уже начинает заканчиваться, вопрос с работой нужно решить как можно скорее.
За прошедший месяц замечено что 16 GB памяти уже не канает. Надо 32 и монитор 4K, дуймов так хотя бы 32. Два монитора, 27" и 34", для работы самое то.
Прошедшая неделка выдалась вообще непростой, но производительной. И по поиску работы и по своим проектам. Но выхи уйдут на блекболыча, опять сделано очень много для работы с контентом, ожидается много всякого интересного. В музыкальных видосах появилась возможность фильтрации контента. Потом надо будет провести такое по всему сайту. Просто и быстро найти контент очень важный момент.
Сейчас найти, например, Crypta, Nervosa, Visions of Atlantis - дело пары секунд.
Постепенно реанимируется, развивается, улучшается сайт с аудио всякими. Там ещё надо много чего сделать, но процесс пошёл. Этому сайтику конечно далеко до других подобных сервисов, а это что там тут нам не надо. Не надо здесь и всё. Что есть то уже хорошо, вот например «Сказ про Федота-стрельца, удалого молодца» Леонида Филатова.
Поиски работы наверное скоро доведут меня до цугундера, проводить за компуктером часов 30 в сутки это уже как-то не очень. Хочется просто взять лопату и пойти в поля тупо копать землю, или в лесу деревья валить. Тем же агентствам по подбору персонала и HR тоже не позавидуешь, у них такие объёмы информации что только держись.
Помимо поиска работы ещё умудряюсь заниматься своими проектиками, всё потихоньку движется вперёд, развивается. К концу года здесь всё будет ещё круче, но вопрос привлечения зарегистрированных пользователей остаётся открытым. И очень непростым. Да во всём виноваты Facebook и Twitter, про других даже не говорю.
Неделя обещает быть вообще нескучной, в контексте поиска работы. Вчера/сегодня постоянные переписки, назначение встреч, вакансии, звонки, интервью, тесты. Но это хорошо, страшно когда вокруг тебя звенящая тишина и тебя не хотят трогать даже десятиметровой палкой. По многим вакансиям предлагают переехать на Мальту, Кипр, в Польшу, Швейцарию и т. д., но мне это как-то не в цвет. Хотя деньги там были бы наверное нешуточные. Вообще надо пошевелить умишком, насчёт переезда. В некоторых компаниях надо приезжать в офис хотя бы раз в месяц. В Польшу, Швецию... Зачем?..
Переезд означает что жизнь изменится очень сильно и там везде ты будешь чужим, эмигрантом. Ты айтишник, хороший специалист? Да всем похуй.
Выходные не прошли даром. Для сайта
сообщества сделано очень много. Лиха беда начало.

Разработка сайта сообщества идёт нормально так, одно из самых главных там это уровень безопасности и изолированности. Чтобы было просто технически невозможно залезть в чужой контент и творить там всякое. Ну и возможности управления контентом тоже на первом месте. Дело ещё осложняется тем что во всех соцсетях доступ возможен только для авторизованных посетителей. Но мы лёгких путей не ищем, анонимы тоже смогут что-то постить (на случай нарушения беспорядков есть механизм банов), и авторы контента смогут устанавливать уровень доступа.
Чем мне самому нра этот новый сайт (раздел сайта...) - там будет можно постить вообще всё без определённой тематики. Впереди ещё огроменный объём работы, но получиться должно интересно. В общем-то ничего нового, этакая Мордокнига на минималках, но для блекболыча это большой шаг, шажище, на пути к захвату цифровой Вселенной.
Подошла к концу ещё одна рабочая неделька, по вакансиям результата 0. "Чел, у тебя охренительный опыт, но... взять на работу мы тебя не можем." Прислали результаты тестирования на HackerRank из польской компании, тест прошёл, но "команды уже укомплектованы, а ты сходи-ка погуляй".
Копаем дальше. Но на LinkedIn приняли в две .NET группы, послал заявку недели три назад, хоть какая-то радость. Теперь впереди два дня контентного безумия на блекболыче.
Потихоньку идёт работа над сайтом сообщества, местной микросоциалочки, думается что к апрелю-маю всё будет по красоте. Спешить некуда потому что никто туда ничего постить не будет.
Компания из Польши рассмотрела мою кандидатуру, вроде бы хотят сотрудничать. На вопрос могу ли переехать в Польшу, ответил что не вижу особого смысла переезжать потому что за последние 6 лет все мои проекты, даже когда был в Риге в офисе, были международные, в удалённом режиме. Okay... Тогда спросили могу ли раз в месяц приезжать в офис? Ожидаемый зарплатос €55,000 в год (до уплаты налогов), думаю надо постараться попасть в эту компанию.
Доработка добавления песен с русскими именами файлов дала нормальный такой результат. Если раньше на добавление альбома уходило примерно минут 15-20, то сейчас не больше 5. Прогресс. Теперь русскоязычных групп будет появляться всяко больше.
Борода Бабая - Борода Бабая
2021
1. Поздний гость
2. Чёрная метка
3. Прощай
4. Любовь людоеда
5. Сказочник Бабай
6. Колобок
7. Быть человеком
8. Самогонка
9. Разговор со смертью
10. Колобок (Live 2019)
11. Поздний гость (Live 2019)
12. Сказочник Бабай (Live 2019)
Это всё конечно интересно и хорошо, но мне от этого ни жарко ни холодно. Страшно представить что будет когда появится выделенный сервер.

Местные инструменты управления контентом развились настолько что сейчас можно невозбранно начать работу над сайтом сообщества на полную мощность. Делать сразу «на все деньги» смысла нет, там большой объём работы и есть риск что это никому не нужно и не интересно. Но блекболыч должен быть готов к новому серверу.
Во дела, в нормальной обстановке, без спешки сделал тест по вакансии как белый человек. Вчера на этот тест после 37 теоретических вопросов оставалось всего 30 минут. Это не дело.

В таком состоянии отослал:

Сегодня всё по красоте:

BankController.cs
using InternetBankingRESTfulService.Api;
using InternetBankingRESTfulService.Api.Core;
using Microsoft.AspNetCore.Mvc;
namespace InternetBankingRESTfulService.Web.Controllers
{
[ApiController]
[Route("[controller]")]
public class BankController : ControllerBase
{
private InternetBankingApi BankingApi { get; }
public BankController()
{
BankingApi = new InternetBankingApi();
}
[HttpGet("api/version")]
public IActionResult GetApiVersion()
{
return Ok(BankingApi.GetApiVersion());
}
[HttpGet("api-version")]
public IActionResult GetApiVersionSecond()
{
return Ok(BankingApi.GetApiVersion());
}
[HttpGet("api/calc/MD5/{value}")]
public IActionResult CalculateMD5(string value)
{
return Ok(BankingApi.CalculateMD5(Helper.ReplaceDigitsByString(value)));
}
[HttpGet("api/calc/{value}/MD5")]
public IActionResult CalculateMD5Second(string value)
{
return Ok(BankingApi.CalculateMD5(Helper.ReplaceDigitsByString(value)));
}
[HttpGet("api/password/strong/{value}")]
public IActionResult PasswordStrong(string value)
{
return Ok(BankingApi.IsPasswordStrong(value));
}
[HttpGet("api/is-password-strong/{value}")]
public IActionResult IsPasswordStrong(string value)
{
return Ok(BankingApi.IsPasswordStrong(value));
}
}
}
InternetBankingApi.cs
using InternetBankingRESTfulService.Api.Core;
using System;
namespace InternetBankingRESTfulService.Api
{
public class InternetBankingApi : IInternetBankingApi
{
private readonly string _apiVersion = $"{DateTime.UtcNow:yyyy.MM.dd}.1.0";
public string GetApiVersion()
{
return _apiVersion;
}
public string CalculateMD5(string value)
{
return Security.MD5Encode(value);
}
public bool IsPasswordStrong(string password)
{
return Security.IsPasswordStrong(password);
}
}
}
Security.cs
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Linq;
namespace InternetBankingRESTfulService.Api.Core
{
public static class Security
{
/// <summary>
/// Returns MD5 hash string.
/// </summary>
/// <param name="plainText"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static string MD5Encode(string plainText)
{
if (string.IsNullOrEmpty(plainText))
throw new ArgumentException("Text cannot be empty.");
return string.Concat(MD5.HashData(Encoding.UTF8.GetBytes(plainText)).Select(x => x.ToString("x2"))).ToUpper();
}
/// <summary>
/// Validate password strength.
/// </summary>
/// <param name="plainPassword"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static bool IsPasswordStrong(string plainPassword)
{
if (string.IsNullOrEmpty(plainPassword))
throw new ArgumentException("Password cannot be empty.");
return new Regex(@"(?=^.{12,}$)(?=.*\d)(?=.*[!@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$").IsMatch(plainPassword);
}
}
}
Helper.cs
using System.Text.RegularExpressions;
namespace InternetBankingRESTfulService.Api.Core
{
public static class Helper
{
/// <summary>
/// Replace all digits in value parameter by char.
/// </summary>
/// <param name="value"></param>
/// <param name="replaceNumberBy">Default char value is 'X'.</param>
/// <returns></returns>
public static string ReplaceDigitsByString(string value, string replaceDigitBy = "X")
{
return Regex.Replace(value, @"\d", replaceDigitBy);
}
}
}
ApiTest.cs
using Microsoft.AspNetCore.Mvc.Testing;
using NUnit.Framework;
using System;
using System.Globalization;
using System.Threading.Tasks;
namespace InternetBankingRESTfulService.Tests
{
public class ApiTest
{
[Test]
public async Task TestApiVersion()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync("/bank/api/version");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual($"{DateTime.UtcNow.ToString("yyyy.MM.dd", CultureInfo.InvariantCulture)}.1.0", data);
}
[Test]
public async Task TestApiVersion_Second()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync("/bank/api-version");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual($"{DateTime.UtcNow.ToString("yyyy.MM.dd", CultureInfo.InvariantCulture)}.1.0", data);
}
[Test]
public async Task TestPasswordStrongIsFalse()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync($"/bank/api/password/strong/123");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual("false", data);
}
[Test]
public async Task TestPasswordStrongIsTrue()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync($"/bank/api/password/strong/ALhj89*19896");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual("true", data);
}
[Test]
public async Task CalculateMD5()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync($"/bank/api/calc/MD5/test-string-ABC");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual("79C8DC4F3BAEBF0A4F40517225F41A86", data);
}
[Test]
public async Task CalculateMD5_SecondURL()
{
var factory = new WebApplicationFactory<Startup>();
var Client = factory.CreateClient();
var result = await Client.GetAsync($"/bank/api/calc/test-string-ABC/MD5");
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
var content = result.Content;
var data = await content.ReadAsStringAsync();
Assert.AreEqual("79C8DC4F3BAEBF0A4F40517225F41A86", data);
}
}
}
В детстве хотел себе мопед Delta, но что-то не сложилось.

Теперь мне неистово нужен NAS.

Только что закончил на DevSkiller очередной тест для вакансии, 2 ч. 30 мин. 37 вопросов + 1 практическое задание. По теории вроде норм, не совсем провально, а тест по разработке Web API закончить не успел, оставшиеся 35 минут это маленько не того. Но сделаю ход конём, закончу тестик без суеты и в понедельник зашлю по почте, типа вот, готово, прошу понять и простить. Ненавижу программить на время когда в лютом цейтноте подгорает пукан и бомбит от каждого неверного шага.
Появились альбомы панк банды «Роковой Год». Приемлемо, то что надо. На сайте как-то мало русскоязычных групп, это никуда не годится.

Впереди практически 3 дня работы над контентом. Место на диске начинает заканчиваться, но пока не критично. Не может не радовать то что инструменты управления сайтом развились настолько что можно колбасить контент не буксуя на мелочах.
В нейросети https://creator.nightcafe.studio/ попросил нарисовать картину по запросу «black cat with whiskey».

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

Сегодня занимался ещё одним тестом. Ограничение по времени 80 минут. 3 задания: 2 по 30мин. и 1 на 20 мин.
Задание #1.
In a Word-Search Puzzle, the player receives a rectangular-shaped grid of letters (a board) and a list of target words. The player is required to locate each target word from the list on the board.
In this question, you are asked to implement a function that receives as input a two-dimensional array of characters and a target word, and returns “true” if the target word appears in the array and “false” if it doesn’t.
For example, given the array
[
['b', 'a', 'n', 't'],
['c', 'f', 'r', 'g']
]
and the target word "ant",
the function should return "true" (because the word appears horizontally in the top row).
Note - the words must appear either horizontally or vertically (not diagonally). All the letters of the word must appear contiguously (i.e., with no unrelated letters in between).
Examples:
Input:
board = [ ['f', 'g', 'a', 'b'], ['b', 'o', 't', 't'], ['e', 'd', 'x', 'p'] ]
targetWord = "dog"
Output: true
Input:
board = [ ['g', 'h', 'c'], ['f', 'm', 'o'] ]
targetWord = "go"
Output: false
Начал делать этот тест, но потом просто забил на это. В общем ещё одна вакансия долой.
Буду готовиться к следующему тестику.
Страница 4 из 6
« следующие заметки 1
2
3
4
5
6
предыдущие заметки »