97 Things Every Programmer Should Know
Get 97 short and extremely useful tips from some of the most experienced and respected practitioners in the industry, including Uncle Bob Martin, Scott Meyers, Dan North, Linda Rising, Udi Dahan, Neal Ford, and many more. They encourage you to stretch yourself by learning new languages, looking at problems in new ways, following specific practices, taking responsibility for your work, and becoming as good at the entire craft of programming as you possibly can.
There is the 97 Things Every Programmer Should Know project, pearls of wisdom for programmers collected from leading practitioners. You can read through the Contributions Appearing in the Book.
Levenshtein distance
In information theory and computer science, the Levenshtein distance is a metric for measuring the amount of difference between two sequences (i.e. an edit distance). The term edit distance is often used to refer specifically to Levenshtein distance.
The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character. It is named after Vladimir Levenshtein, who considered this distance in 1965. (wikipedia with code, russian version)
- Levenshtein Distance, in Three Flavors (java applet)
- Damerau–Levenshtein distance
- Levenstein distance.beam (slideshare presentation)
Using QString effectively
QLatin1String : Avoid mallocs in operator ”==”
if (fruit== "apple") { ... } // hidden malloc
if (fruit== QLatin1String("apple")) { ... } // fast and mentions encoding
QStringRef : String manipulation without the malloc
QString::reserve and QString::squeeze
QStringBuilder : Fast QString concatenation
if (foo.startsWith("(" + type + ") 0x"))
if (foo.startsWith("(" % type % ") 0x"))
Use QStringMatcher to match a string repetitively
QtService
The QtService component is useful for developing Windows services and Unix daemons.
The project provides a QtService template class that can be used to implement service applications, and a QtServiceController class to control a service.
On Windows systems the implementation uses the Service Control Manager.
On Unix systems services are implemented as daemons.
Single Application
The QtSingleApplication component provides support for applications that can be only started once per user.
For some applications it is useful or even critical that they are started only once by any user. Future attempts to start the application should activate any already running instance, and possibly perform requested actions, e.g. loading a file, in that instance.
The QtSingleApplication class provides an interface to detect a running instance, and to send command strings to that instance.
For console (non-GUI) applications, the QtSingleCoreApplication variant is provided, which avoids dependency on QtGui.
Documentation
- Classes:
- Examples
QThread
QThread was designed and is intended to be used as an interface or a control point to an operating system thread, not as a place to put code that you want to run in a thread. We object-oriented programmers subclass because we want to extend or specialize the base class functionality. The only valid reasons I can think of for subclassing QThread is to add functionality that QThread doesn’t have, e.g. perhaps providing a pointer to memory to use as the thread’s stack, or possibly adding real-time interfaces/support. Code to download a file, or to query a database, or to do any other kind of processing should not be added to a subclass of QThread; it should be encapsulated in an object of it’s own.
// create the producer and consumer and plug them together Producer producer; Consumer consumer; bool bOk = producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce())); Q_ASSERT(bOk); bOk = consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *))); Q_ASSERT(bOk); // they both get their own thread QThread producerThread; producer.moveToThread(&producerThread); QThread consumerThread; consumer.moveToThread(&consumerThread); // go! producerThread.start(); consumerThread.start();
Reference: Threading without the headache or QThread’s no longer abstract (see attached file)
Lies, damned lies and statistics (about TEDTalks)
In a brilliantly tongue-in-cheek analysis, Sebastian Wernicke turns the tools of statistical analysis on TEDTalks, to come up with a metric for creating “the optimum TEDTalk” based on user ratings. How do you rate it? “Jaw-dropping”? “Unconvincing”? Or just plain “Funny”?
debug assertion in Delphi 2009 on Windows 7 64-bit
Using Delphi 2009 on Windows 7 64-bit you can notice about the error dialog during debugging:
Assertion failure: “(!”SetThreadContext failed”)” in ..\win32src\thread32.cpp
The problem is that the executable file is blocked and Delphi 2009 studio must be closed.
The solution is:
Kanban для одного
Что же такое Kanban? Чтобы не запутывать, скажу, что упрощая, систему можно свести к 3-м правилам:
- Визуализируй состояние (Kanban-доска)
- Ограничь количество слотов в каждом из состояний
- Измеряй скорость работы, т.е. среднее время исполнения одной задачи
Задачи переходят из левых колонок в правые, не перескакивая. Приоритизация задач осуществляется в колонке todo, в которую я рекомендовал бы помещать только «большие» задачи: мелочь пусть просачивается между большими, как и положено. Что означают остальные колонки?
- wip — work in progress, то, что я сейчас делаю.
- review — анализ выполненных задач, проверка качества, в программировании это называлось бы «тестированием»
- done — сюда попадают задачи, успешно прошедшие предыдущую колонку. Зачем нужна такая колонка? Объясню, зачем она мне: я знаю за собой особенность, я порой не произвожу «доставку» выполненной работы
Цифры под заголовками — те самые слоты. Они означают, что больше этого числа помещать в колонку нельзя. Эти цифры могут меняться, они просто обязаны меняться.
После каждой «доставки» — например, отправки клиентам выполненной работы, стоит делать «ретроспективу», во время которой обязательно нужно проанализировать, что мешало выполнить работу максимально эффективно и поставить себе задачи на исправление этих «узких мест». При достижении ограничений в любой из колонок, вам стоит бросить все силы на освобождение «слота».