• Как через битовые операции взять остаток от деления?

    yellow79
    @yellow79
    Senior Software Engineer
    Если делителем является степень двойки, то остаток от деления можно получить битовым and но при этом вычесть единицу из делителя. Например 4565567 % 8 = 4565567 & 7
    Если делитель не является степенью двойки, то битовые операции вам не помогут
    Ответ написан
    Комментировать
  • Правильно ли объясняется в тексте почему в 1 кб 1024 байт?

    saboteur_kiev
    @saboteur_kiev Куратор тега Программирование
    software engineer
    Нет, неправильно.
    То, что было в перфокартах для контроля четности - это оставьте перфокартам, контроль четности и кодирование данных никак не связаны с обозначением кило и 1024. И уж тем более 1025 вообще далеко от ИТ.

    Все проще.
    Берем 1 бит, можем оперировать двумя значениями 0 и 1
    2 бита - 4 значения, 0-3
    3 бита - 8, 0-7
    4 бита - 16, 0-15
    5 бит - 32, 0-31
    6 бит - 64, 0-63
    7 бит - 128, 0-127
    8 бит - 256, 0-255
    9 бит - 512, 0-511
    10 бит - 1024, 0-1023

    Нет такого набора бит, чтобы мы могли оперировать ровно 1000 значений. 9 бит мало, а 10 бит позволяют оперировать уже 1024 значениями. Ограничиваьт себя искусственно нет смысла.
    Поэтому на железном уровне в качестве адресации используются степени двойки, чтобы максимально эффективно использовать все используемые биты и память.
    Следовательно ближайшее к 1000 "компьютерное" число это 1024, отсюда в килобайте 1024 байт.

    Для бизнеса это оказалось не очень удобно. И вообще много технических моментов обычным пользователям непонятно почему и как, например с теми же жесткими дисками, когда объем неотформатированного диска и отформатированного может отличаться на заметные процентов 10-15.
    Кроме того, в системе Си, приставки кило, мега, и так далее всегда означали 1000 чего-то. Поэтому с исторически сложившимся 1024 в ИТ отрасли сложилась некомфортная ситуация. Для исправления и появились новые названия, кибибайты, мегибайты, а килобайты и мегабайты по общепринятой системе Си теперь кратны 1000. Но это важно для стандартизации, маркетинга, а не для программирования.

    В программировании ничего не изменилось, и как бы их не называли кибибайт или килобайт, при программировании оперируют степенями двойки, а не десятки.
    Ответ написан
    Комментировать
  • Кто должен логировать? Функция или тот, кто её вызывает?

    artemgapchenko
    @artemgapchenko
    То, что вы описали, называется в англоязычной литературе cross-cutting concerns - это такие области кода, которые решают не саму бизнес-задачу, а являются как бы перпендикулярными к ней, и относятся скорее к функционированию системы. Вы правы насчёт того, что добавлять логирование в саму функцию - это, наверное, не совсем правильный выбор, так как во-первых, функция начинает решать две задачи, что сразу же уменьшает время на понимание её работы, а во-вторых, возможно будут варианты вызова функции, при которых её выполнение логировать не обязательно.
    Я бы, возможно, попробовал зайти к этой задаче со стороны паттерна Декоратор (дальше пишу на Java, так как этот язык для меня основной, но принципы должны быть понятны).

    Определяем интерфейс:

    interface ClientHandler {
    	void blockUser(User user);
    	void unblockUser(User user);
    }

    Дальше пишем реализацию, которая будет заниматься блокированием/разблокированием пользователя:

    public final class ClientHandlerImpl implements ClientHandler {
    	public void blockUser(User user) {
    		// Логика блокирования пользователя
    	}
    
    	public void unblockUser(User user) {
    		// Логика разблокирования пользователя
    	}
    }

    А теперь ход конём: пишем декоратор, который будет оборачивать собой написанную нами имплементацию (и в аргументе конструктора пробрасываем ClientHandlerImpl):

    public final class ClientHandlerLoggingDecorator implements ClientHandler {
    	private final ClientHandler handler;
    
    	public ClientHandlerLoggingDecorator(final ClientHandler handler) {
    		this.handler = handler;
    	}
    
    	public void blockUser(User user) {
    		Log.d("User " + user.getName() + " blocked!")
    		handler.blockUser(user);
    	}
    
    	public void unblockUser(User user) {
    		Log.d("User " + user.getName() + " unblocked!")
    		handler.unblockUser(user);
    	}
    }


    Дальше можно будет создать, например, фабрику ClientHandler'ов, которая по запросу будет возвращать нам новый инстанс ClientHandler'а:

    public final class ClientHandlerFactory {
    	public static ClientHandler getClientHandler() {
    		return new ClientHandlerLoggingDecorator(new ClientHandler());
    	}
    }

    Чего мы добились:
    1. Код логирования вынесен из реализации ClientHandler, если вам нужно будет изучить реализацию блокирования/разблокирования, вы просто открываете ClientHandlerImpl, и изучаете её.
    2. (связано с предыдущим пунктом) Реализацию блокирования/разблокирования и логирования теперь можно менять независимо друг от друга.
    3. Логирующее поведение становится скрытым для пользователей ClientHandler - они просто получают новый инстанс при обращении к фабрике, и используют его. Хотите отключить логирование? Меняете реализацию фабрики, и она начинает возвращать ClientHandlerImpl. Хотите сделать это поведение настраиваемым? Пишете дополнительный код, который на старте читает конфигурацию, и начинает использовать либо ту реализацию фабрики, которая возвращает ClientHandler, покрытый декоратором, либо реализацию, которая возвращает голый ClientHandler. Либо же зашиваете этот выбор внутрь самой фабрики.
    Ответ написан
    Комментировать
  • Как сделать Desktop-приложение на Clojure?

    @chernyatiev
    Есть неплохая обвязка к Swing на  clojure: https://github.com/daveray/seesaw
    Ответ написан
    Комментировать