Docker is a tool designed to make it easier to build, test, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries, system tool, code and runtime, and deploy it as one package.
Here is the list of most used commands that will make developers' life easier.
docker version
docker info
docker run <image name> // e.g.
docker run hello-world
docker run <image name> <command>// e.g.
docker run busybox ls
docker ps
docker ps -a
docker create <image name>
docker create --name <name> <container…
Uploading and downloading files are common tasks for any web application. Spring offers support for these kinds of actions by providing MultipartFile
interface. Let's go over building a simple application which will enable the user to upload/download a file.
The application will be built with Spring boot and will leverage the following libraries:
The file will be stored in database (you can also choose to store file on disk as well). As we wish to send some additional information (who triggered upload, additional description, etc.) when uploading the file, we need to have these as properties in the table. …
There are few applications that do not communicate with the server over the internet to retrieve/push the data. As most of the applications built are using some kind of Application Programming Interface (API), it is good to know how to leverage it for your case. API defines a set of rules which allow programs to communicate with each other (in case of iOS app, that would be the app itself and a remote server hosting the data).
In order to access the data on the specified server you need the address of the resource. To access it you will use Uniform Resource Locator (URL) which represents the location of the data. …
Most of the key factors described here can be applied to the whole team, but the focus of this article is on testers/testing.
When the whole team takes responsibility for testing and quality, a mix of variety of skill sets and experience levels will work together to overcome the challenges which might arise.
By making testers truly part of the development team, understanding of the requirements become clear, product becomes more stable, code quality increases, etc. as they provide a unique viewpoint that will promote delivery of a great product.
The whole team approach involves constant collaboration, where everyone takes responsibility for testing tasks. Having diverse viewpoints can only mean better tests, greater code coverage and delivery of highest possible business value. …
Swift borrows many functional programming concepts, among others: map
, flatMap
and compactMap
. This article will give a closer look at these operations.
Suppose that we have detectives with: name, rank and cases working on. To find out which detectives are heavily involved in solving cases we can implement the following approach
struct Detective {
let name: String
let rank: String
let cases: UInt
}func involvedInCases(detectives: [Detective]) -> [String] {
var involvments = [String]()
for detective in detectives {
let involvment: String;
switch detective.cases {
case 0: involvment = "\(detective.name) is not involved"
case 1...10: involvment = "\(detective.name) is pretty involved"
default: involvment = "\(detective.name) is heavily involved"
}
involvments.append(involvment) …
Imagine that we need to extend Array
with special function which will remove all duplicates. This can be done by referring to Element
as its inner value. In order to check for equality, an array Element
must conform to Equatable
, which can be added as constraint. Constraining Element
to Equatable
means that this method is only available on arrays with Equatable
elements.
extension Array where Element: Equatable {
func unique() -> [Element] {
// implementation
}
}
This looks like a good start, but it is more reasonable to give this extension to other collection types, not only Array
. …
You can think of technical debt as an analogy with friction in a car; the more you use it without properly servicing it, the more energy, time and money you will need to invest when something breaks. Technical debt is not a new concept, it exists from the start of computer engineering and goes hand in hand with software evolution and software maintenance.
Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. …
Imagine that you are creating an app which should, among other things, track analytics events. For this you have chosen one of the event tracking systems (e.g. Firebase).
The first idea would be to create a struct that will model AnalyticsEvent
.
struct AnalyticsEvent {
let userId: String
let hasAdditionalData: Bool
let additionalData: [String: String]
let hasFeedback: Bool
let feedbackContent: String
// rest of the properties
}
Although this is a hypothetical situation, it highlights a problem. Because struct can contain multiple values, bugs may arise if multiple events are contained in one command (e.g. hasFeedback
and hasAdditionalData
). …
Imagine that you are creating an app which should, among other things, track analytics events for user metrics. For this you have chosen one of the event tracking systems (e.g. Firebase).
AnalyticsProtocol
is declared and can be implemented on UIViewController
with default implementation. This will add the functionality of AnalyticsProtocol
to all UIViewController
types and its subclasses.
Conforming all view controllers to this protocol is probably not the best idea. If you are delivering a framework with this extension, a developer implementing this framework will get this extension automatically, whether they like it or not. …
Finally, you are done with the new feature, you have opened Pull Request and hope it will get merged soon. Unfortunately, reality is that your PR might be sitting there for a while. Meanwhile, development goes on and the branch you are targeting with your PR gets updated.
While this happens, conflicts may arise. These are conflicts between your code changes in the PR and other changes that got merged into the target branch. What you could do is merge the changes from the target branch into your PR branch or do a rebase.
Git merge and rebase serve the same purpose. They are designed to integrate changes from one or multiple branches into one. Although the final goal is the same, those two methods achieve it in different ways, and it’s helpful to know the difference. …