Пишу о программировании, книгах, науке и жизни
Ctrl + ↑ Позднее

Пример хорошего письма

1 ноября 2015, 16:04

Считается дурным тоном:
— начинать письмо с фразы «Доброго времени суток»
— использовать !!!
— ФОРМУЛИРОВАТЬ МЫСЛЬ ПРОПИСЬЮ
— использовать «:-))))))» вместо «:-)»
— не делить большой текст на абзацы
— писать «Вы» вместо «вы», если местоимение не стоит в начале предложения
— снабжать текст... многоточием...
— прикреплять огромную картинку, когда можно обойтись небольшой
— использовать формат письма html
— вставлять огромные цитаты, когда есть возможность сослаться на ресурс
— сохранять в письме днище из всей предыдущей переписки

Признаки хорошего тона:
— писать коротко и по делу
— цитировать смысловую часть или разбивать цитату на блоки

Источник: Сергей Стеблина

Точка с запятой

22 октября 2015, 1:24

Цитата неизвестного:

Существуют языки программирования, которые прекрасно обходятся без точки с запятой.

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

Точка с запятой впервые появилась в Алголе‐58, во времена, когда символы переноса строки и возврата каретки считались несущественными и можно было лепить исходный код в однострочную нечитаемую мешанину. Однако же другие языки программирования прекрасно выживают без точек с запятой, им нет нужды дублировать символы конца строки, которые итак вставляет любой текстовый редактор по нажатию на Enter.

Все аргументы защитников повсеместного применения точек с запятой сводятся к тому, что так принято, так все привыкли, это архаизм древних языков 1958 года, который «невозможно» отменить. Мало того, в большинстве си‐подобных языков эта идиома намеренно введена в синтаксис и стандарт как обязательная. Теперь программист всегда должен выполнять лишнюю работу и ставить этот символ перед тем, как нажать на Enter.

Трудность даже не в том, что приходится каждый раз в конце строки ставить точку с запятой, эту задачу вполне могла бы решать интегрированная среда разработки или препроцессор. Трудность в том, что поставленная точка с запятой перед или после некоторых символов (например, «{», «}» в си или операторов «End» в паскалях) вызывает ошибку компиляции. В каком‐то месте кода точка с запятой обязательна, в каком‐то её можно опустить, а в каком‐то месте её вдруг ставить вообще нельзя — логику такого непоследовательного поведения объяснить невозможно, это можно только зазубрить.

Современные компиляторы вполне справляются с листингом, где для конца строк используются только два символа (с кодами 10 и 13), а не три, как в си и производных от него языках. Простой пример.
На VB.Net можно написать вот так:
Dim f = 32 / 4
Dim g = 25 / 5
Или вот так
Dim f =
32 / 4
Dim g = 25 / 5
Всё это будет валидным кодом. Компилятор сам умеет определять, является ли конец строки также и окончанием оператора, а если оператор не закончен на текущей строке, то он будет поглощать выражение из следующей строки.

Увы, в си такое поведение компилятора просто невозможно, потому что стандарт обязывает всегда указывать конец оператора, даже если он совпадает с концом строки.

Курс молодого бойца

20 октября 2015, 9:07

Практический курс для новичков в мире сетевых технологий. Посмотрев данный материал вы научитесь пользоваться программным симулятором Cisco Packet Tracer и познакомитесь с основными понятиями, технологиями и приемами, которые используются при построении корпоративных сетей. Курс исключительно практический и содержит минимум теории, что делает его не таким утомительным.

https://www.youtube.com/playlist?list=PLcDkQ2Au8aVNYsqGsxRQxYyQijILa94T9

Как открыть сберегательный счет в Сбербанке

19 октября 2015, 18:45

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

  1. Идём в Сбербанк и просим консультанта выдать вам чек в окошко, где оформят «Заявление на банковское обслуживание».
    Эта бумажка позволит вам управлять счетами через «Сбербанк.Онлайн», он, к слову, стал довольно удобным.
  2. Дожидаетесь очереди, даёте паспорт, говорите «хочу управлять вкладами через интернет». Оператор печатает вам заявление, вы расписываетесь и счастливый идёте домой.

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

Джоэл о программном обеспечении

16 октября 2015, 15:43

Все статьи рекомендованы к прочтению:
http://russian.joelonsoftware.com/

Джоель Спольски — основатель Fog Creek Software, небольшой компании по
разработке программного обеспечения, расположенной в Нью-Йорке.
Окончил Йельский Университет, работал программистом и управляющим в
Microsoft, Viacom и Juno.

Закон дырявых абстракций

3 октября 2015, 12:40

Статья 2000 года, каждый абзац которой можно разобрать на цитаты.
http://russian.joelonsoftware.com/Articles/LeakyAbstractions.html

TCP

Волшебство же состоит в том, что TCP основан на IP. Иными словами, TCP обязуется работать надёжно, используя лишь ненадёжные детали.

Погода

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

С++

Интересно, что историю развития C++ можно описать как историю затыкания дырок в абстракции строк. Уж не знаю, отчего бы не добавить к языку элементарный класс строчек.

Ссылка или сам объект?

29 сентября 2015, 10:17

Вопрос

Я заметил, что нередко программисты, чьи коды я видел, используют указатели на объекты чаще, чем сами эти объекты, т. е. например, используют следующую конструкцию:

Object *myObject = new Object;

вместо:

Object myObject;

Аналогично с методами. Почему вместо этого:

myObject.testFunc();

мы должны писать вот это:

myObject->testFunc();

Я так понимаю, что это дает выигрыш в скорости, т. к. мы обращаемся напрямую к памяти. Верно? P.S. Я перешел с Java.

Ответ

Заметим кстати, что в Java указатели не используются в явном виде, т. е. программист не может в коде обратиться к объекту через указатель на него. Однако на деле в Java все типы, кроме базовых, являются указателями. Соответственно, и обращение к ним происходит по ссылке, хотя явно передать параметр по ссылке нельзя. И еще, на заметку, new в C++ и Java или C# — абсолютно разные вещи.

Для того, чтобы дать небольшое представление, что же такое указатели в C++, приведем два аналогичных фрагмента кода:

Java

Object object1 = new Object(); // Новый объект 
Object object2 = new Object(); // Еще один новый объект 
object1 = object2;
// Обе переменные ссылаются на объект, на который раньше ссылалась object2
// При изменении объекта, на который ссылается object1, изменится и
// object2, потому что это один и тот же объект

Ближайший эквивалент на C++

Object * object1 = new Object(); // Память выделена под новый объект
// На эту память ссылается object1
Object * object2 = new Object(); // Аналогично со вторым объектом 
delete object1;
// В C++ нет системы сборки мусора, поэтому если этого не делать,
// к этой памяти программа уже не сможет получить доступ
// И, на самом деле, к ней уже никто не получит доступ,
// как минимум, до перезагрузки
object1 = object2; // Как и в Java, object1 указывает туда же, куда и object2

Однако вот это — совершенно другая вещь (C++):

Object object1; // Новый объект 
Object object2; // Еще один 
object1 = object2;
// Полное копирование объекта object2 в object1,
// а не переопределение указателя – очень дорогая операция

Я так понимаю, что это дает выигрыш в скорости, т. к. мы обращаемся напрямую к памяти.
На самом деле, совсем нет. Работа с указателями оформлена в виде кучи, в то время как работа с объектами — это стек, более простая и быстрая структура.

Строго говоря, этот вопрос объединяет в себе два различных. Первый: когда стоит использовать динамическое распределение памяти (new)? Второй: когда стоит использовать указатели? Естественно, здесь не обойдемся без общих слов о том, что всегда необходимо выбирать наиболее подходящий инструмент для работы. Почти всегда существует реализация лучше, чем с использованием ручного динамического распределения (dynamic allocation) или/и сырых указателей.

Динамическое распределение

В формулировке вопроса представлены два способа создания объекта. И основное различие заключается в сроке их жизни (storage duration) в памяти программы. Используя Object myObject;, вы полагаетесь на автоматическое определение срока жизни, и объект будет уничтожен сразу после выхода из его области видимости. А вот Object *myObject = new Object; сохраняет жизнь объекту до того момента, пока вы вручную не удалите его из памяти командой delete. Используйте последний вариант только тогда, когда это действительно необходимо. А потому всегда делайте выбор в пользу автоматического определения срока хранения объекта, если это возможно.

Обычно принудительное установления срока жизни применяется в следующих ситуациях:

  1. Вам необходимо, чтобы объект существовал и после выхода из области его видимости — именно этот объект, именно в этой области памяти, а не его копия. Если для вас это не принципиально (в большинстве случаев это так), положитесь на автоматическое определение срока жизни. Однако вот пример ситуации, когда вам может понадобиться обратить к объекту вне его области видимости, однако это можно сделать, не сохраняя его в явном виде: записав объект в вектор, вы можете «разорвать связь» с самим объектом — на самом деле он (а не его копия) будет доступен при вызове из вектора.
  2. Вам необходимо использовать много памяти, которая может переполнить стек. Здорово, если с такой проблемой не приходится сталкиваться (а с ней сталкиваются очень редко), потому что это «вне компетенции» C++, но к сожалению, иногда приходится решать и эту задачу.
  3. Вы, например, точно не знаете размер массива, который придется использовать. Как известно, в C++ массивы при определении имеют фиксированный размер. Это может вызвать проблемы, например, при считывании пользовательского ввода. Указатель же определяет только тот участок в памяти, куда будет записано начало массива, грубо говоря, не ограничивая его размер.

Если использование динамического распределения необходимо, то вам стоит инкапсулировать его с помощью умного указателя или другого поддерживающего идиому «Получение ресурса есть инициализация» типа (стандартные контейнеры ее поддерживают — это идиома, в соответствии с которой ресурс: блок памяти, файл, сетевое соединение и т. п. — при получении инициализируется в конструкторе, а затем аккуратно уничтожается деструктором). Умными являются, например, указатели std::unique_ptr и std::shared_ptr.

Указатели

Однако есть случаи, когда использование указателей оправдано не только с точки зрения динамического распределения памяти, но почти всегда есть альтернативный путь, без использования указателей, который вам и следует выбрать. Как и ранее, скажем: всегда делайте выбор в пользу альтернативы, если нет особенной необходимости в использовании указателей.

Случаями, когда использование указателей можно рассматривать как возможный вариант, можно назвать следующие:

  1. Ссылочная семантика. Иногда может быть необходимо обратиться к объекту (вне зависимости от того, как под него распределена память), поскольку вы хотите обратиться в функции именно в этому объекту, а не его копии — т. е. когда вам требуется реализовать передачу по ссылке. Однако в большинстве случаев, здесь достаточно использовать именно ссылку, а не указатель, потому что именно для этого ссылки и созданы. Заметьте, что это несколько разные вещи с тем, что описано в пункте 1 выше. Но если вы можете обратиться к копии объекта, то и ссылку использовать нет необходимости (но заметьте, копирование объекта — дорогая операция).
  2. Полиморфизм. Вызов функций в рамках полиморфизма (динамический класс объекта) возможен с помощью ссылки или указателя. И снова, использование ссылок более предпочтительно.
  3. Необязательный объект. В этом случае можно использовать nullptr, чтобы указать, что объект опущен. Если это аргумент функции, то лучше сделайте реализацию с аргументами по умолчанию или перегрузкой. С другой стороны, можно использовать тип, который инкапсулирует такое поведение, например boost::optional (измененный в C++14 std::optional).
  4. Повышение скорости компиляции. Вам может быть необходимо разделить единицы компиляции (compilation units). Одним из эффективных применений указателей является предварительная декларация (т. к. для использования объекта, вам необходимо предварительно его определить). Это позволить вам разнести единицы компиляции, что может положительно сказаться на ускорении времени компиляции, внушительно уменьшив время, затрачиваемое на этот процесс.
  5. Взаимодействие с библиотекой C или C-подобной. Здесь вам придется использовать сырые указатели, освобождение памяти из под которых вы производите в самый последний момент. Получить сырой указатель можно из умного указателя, например, операцией get. Если библиотека использует память, которая в последствии должна быть освобождена вручную, вы можете оформить деструктор в умном указателе.

Источник: stackoverflow.com
Перевод: vk.com

Прослушка

26 сентября 2015, 23:18

Хороший сериал, затягивающий.
Не стоит ждать с первых серий рассказов о всяких крутых штуках для скрытого прослушивания, у сериала совсем другая история.
Использование прослушки лишь часть сюжета и первый сезон — только пролог.
Поэтому в сериал нужно вникнуть, как в хорошую книгу, у меня он зашёл только со второго раза.

P.S Омар Литтл насвистывает песенку Childrens Music — The Farmer In The Dell

UPD1 Конец второго сезона шедевральный.
UPD2 И третьего тоже.

Конец 4-го сезона неинтересный, а вот конец 5-го, т. е. конец всего сериала, хорош.

Ctrl + ↓ Ранее