Shortcut to seniority
Home
Go to main page
Section level: Junior
A journey into the programming realm
Section level: Intermediate
The point of no return
Section level: Senior
Leaping into the unknown
                    Go to main page
A journey into the programming realm
The point of no return
Leaping into the unknown
Software / Programming paradigms are a way to classify the programming languages based on their approach to solve problems.
Common programming paradigms include:
Imperative programming focuses on how to execute, and defines the control flow as statements that change the state of the application. The main focus is on how to achieve the goal.
We can divide imperative programming into two broad categories:
Procedural programming paradigm emphasizes on procedures (groups code into procedures), and main traits include using local variables, sequences, and iterations. Procedural language describes, step by step, the procedures that should be followed to solve a specific problem.
Object oriented programming focuses on writing classes to write applications. The classes encapsulates data (fields/attributes) and code (methods) which are related. An object is said to be an instance of a particular class.
In OOP, the only way that an object can access the data is through its methods. Therefore, the internal logic can be changed without affecting any code that uses the object.
Declarative programming is a style of building programs that expresses logic of computation without talking about its control flow.
We can divide declarative programming into three broad categories:
Logic programming paradigm is based on formal logic, and any program written in a logic language is a set of sentences in logical form.
Functional programming has its roots in mathematics. It treats programs as evaluating mathematical functions and avoids state and mutable data. In functional code, programming is done with the use of expressions and declarations instead of statements. The output value of a function is dependent only on the input arguments – the same result will be outputed each time we call a function with the same arguments.
The key motivations for functional programming is the elimination of side effects, to make it easier to reason, understand, and predict the behavior of an application.
Database / data driven programming approach is based on data and its movement.
There are various approaches defined that are used throughout the process of a software. These approaches are defined as “Software Development Process Models”. Each process model follows a particular life cycle, and describe the phases of the software and the order in which they are executed.
Each of this phase produce deliverables that are further used in the next phase of the process.
This phase is mainly the focus of project managers and other stakeholders. In this phase, the requirements need to be defined, and for doing so, there are some general questions that need to be answered, such as: Who are the users of the system? How will they use it? etc.
After the requirements were gathered, they are analyzed and validated. It is very important for all the people involved during this step to have a clear view regarding what is expected from the development team, and to clarify any specification-related problems, while also taking into account the limitations of the system / hardware.
As guidelines for the model, a requirements specification document has to be created.
This phase is responsible for the system and software design, and as input, it uses the requirements specifications which were studied in the first / initial phase. System design helps in specifying hardware and system requirements, while also being used for defining the overall system architecture.
The System design specifications are used as input for the next phase of the model.
This phase is where the actual code is produced, and is the main focus for the developer. Using the system design documents as reference, the work is further divided into modules. This is the longest phase of the software development life cycle.
After the code is written, it is tested against the requirements to make sure that the product is solving the needs that were gathered during the requirements phase. Any issues encountered during this phase will lead back to the coding activity, before delivering the software to the customer.
After the testing was successfully performed and no major issues were found, the product is delivered to the customer. The customer will then check whether there are some changes required, and also check the system for bugs, and report them to the engineering team. After the changes are made and / or the bugs are fixed, the final delivery will occur.
Maintenance phase starts as soon as the customers starts using the product. During this step, the maintainers of the product will solve the problems that are reported by the customers. The delivery / updates will occur less often, typically once every 3-6 months, and each fix will have to be intensively tested to assure that no regression will occur.
The Waterfall Model was the first process model introduced. It is the easiest to understand and use, and it shines in small projects or in projects in which specifications are well defined and set in stone, from the beginning of the project. In a waterfall model, each phase must be fully completed before the next phase is started.
Usually, after one phase ends, a review is done in order to validate the completion of that phase, and to start the next one.
                                            The interaction with the customer is not that big during the development phase, and once the product is ready, a demo can be done to the end users.
Agile was created as a need for projects in which the environment is unstable and always changes. It is an iterative approach in which the software development teams provides a binary for their customers much more often.
Each deliverable contains a few (or only one) full features, meaning that the agile team is going through all the phases (evaluate specifications, design, implement, test) for that specific feature that is expected by the customer. This way, the teams have a natural mechanism for responding quickly to change.
Many Agile frameworks were created on top of agile methodology, including Scrum, Kanban, Lean, or Extreme Programming.
                                            The model should be used only when:
The Verification and Validation model, also called the V-model, follows the footsteps of the waterfall model. Its lifecycle is a sequential path of execution of processes.
                                            Requirements (BRS, SRS) are the first phase of the life cycle, similar to the waterfall model. The difference in this model is that a system test plan is created before the development has even started. That test plan focuses on passing the functionality that is specified in the requirements.
The high-level design (HLD) phase focuses on system architecture and design. The idea is to have an overview of the product and a starting point for the architecture. At the same time, an integration test plan is created in order to test the integration of the pieces altogether.
The low-level design (LLD) phase is where the actual software components are created. In this step, we should define the actual logic for the components (modules). Output of this phase should be the class diagrams and component tests.
The implementation phase is where the development is done. Once the coding is complete, the path of execution continues up the right side of the V-model where the test plans developed earlier are now verified against the code.
The coding phase is at the bottom of the V-model. Unit tests are created on the code written during the implementation phase.
The V-model should be used in small projects, where requirements are clear and fixed.
Extreme programming (XP) is a software development methodology that was created for improving the software quality and responsiveness to changing customer requirements.
Elements of XP include programming in pairs, extensive code reviews, unit testing, avoiding feature implementation until is actually needed, code simplicity and clarity, frequent communication with the customer, and assumptions/expectations that the requirements will change in time.
Extreme programming attempts to reduce the cost of changes in requirements by having multiple short development cycles, instead of a long one. It is successful because its main focus is customer satisfaction, constantly communicating and delivering the system as early as possible, and implementing changes as suggested by the customer.
Pair programming is a technique in which two programmers work together at one workstation. One of them, called the driver, is writing the code while the other, called the observer, reviews each line of code as it is typed in. The two programmers switch roles frequently.
“Why would we want to do that ? I don’t want to be social, I want to write code.”. When two people work together, it’s ineffective. If two programmers work alone, they can do twice as much, right?
But then there’s bugs. Crazy bugs, that takes us hours or even days to fix.
Yes, that won’t happen to you, you’re a great programmer, but to the others… it might happen!
“So, if we do pair programming, we won’t have bugs?” – Of course you’ll have. But less than you’d have if you had coded alone. And I’m not talking about bugs that are caught during code review, but ones that are way harder to detect.
                                                        You’ll have a stronger architecture. Two minds are better than one.
You can discuss strategies together, and find the best / optimal solution. It’s also harder to procrastinate.
And obviously, you’ll also learn things from each other (knowledge sharing), and increase collaboration between colleagues.
Mob programming is a technique in which the entire team works together at one workstation. This is similar to pair programming, but now, the collaboration is extended to everyone on the team, while still using a single computer for writing the code.
Scrum is an agile framework for work management. It is designed for teams of three up to nine developers, who break their work into tasks that can be completed within iterations (called sprints) which usually last 2-3 weeks, and track the progress in 15-minutes stand-up meetings (daily scrums).
The Product Backlog is a list of tasks (features, requirements, enhancements, fixes) that are needed to be developed for the end product to be finished. The Product Backlog is constantly changing based on updates received on the specification, client feedback, findings, etc.
The Product Owner is responsible for the Product Backlog, including its content, availability, and ordering.
The Sprint Backlog is a list of tasks that were selected for the Sprint, along with a plan for delivering the increment (the product; see below) and realizing the sprint goal. The Sprint Backlog contains the functionality and the work needed to deliver it, as judged by the Development Team.
The Sprint Backlog solely belongs to the Development team, and they are in charge of adding new tasks (when new work is required), updating the estimated remaining work (as work is performed or completed), or removing them entirely (when some of them are deemed unnecessary).
The Increment can be seen as the sum of all the Product Backlog Items completed during the Sprint and the value of the increments from previous Sprints. For the development team, the increment is a step towards a vision or goal, and should be in a usable condition and meet the Scrum Team’s definition of Done.
There are three roles involved in the scrum: The product owner, the scrum master, and the development team member.
The product owner is responsible for managing the product backlog, and for maximizing the value of the product resulting from work of the development team.
The development team is formed by software professionals that are responsible for the work packages that have to be delivered within a sprint, and for the delivery of the potentially releasable increment product at the end of each sprint.
The Scrum Master is helping everyone understand Scrum practices, rules, and values, as defined in the Scrum guide.
The Scrum Master serves the Product Owner by:
The Scrum Master serves the Development team by:
The Scrum Master serves the organization by:
The sprint is the time in which the releasable product increment is created. It has consistent duration throughout the development effort (usually 2-3 weeks, no more than one month), and it starts immediately after the conclusion of the previous Sprint has ended.
Sprint contains Sprint planning, Daily scrums, Development work, Sprint review, and Sprint retrospective.
Sprint Planning is where the tasks are planned for the upcoming sprint. The plan is created by collaborating with the entire scrum team.
The Sprint Planning answers the following questions:
Topic one: What can be done this sprint?
The entire team joins a meeting in which they decide what will be added into the sprint.
The input in the meeting will be the product backlog, the latest increment, and the capacity of the development team (which is diminished by days off or national holidays). The team will then select the tasks that can be added into the sprint. Each sprint should also have a sprint goal attached, as guidance throughout the sprint.
Topic two: How will the chosen work get done?
Now that the items were added into the sprint, the development team discuss about how they will implement the functionality. The product owner also has to make sure that all the chosen items are clear or otherwise clarify them with the team.
The Sprint Goal is an objective set for the sprint, and should be achieved by implementing tasks fetched from the Product Backlog. It is created during the sprint planning meeting, and it gives some flexibility regarding the functionality implemented in the sprint.
The Daily Scrum is a 15 minutes daily meeting with the development team, in which the team plans the work for the current day. The usual stand-up answers the following questions:
The Scrum Master ensures that the development team attend the meeting and that it is kept in the 15 minutes time frame, but the development team is responsible for conduction the daily scrum.
A Sprint Review is a meeting that takes place at the end of the sprint and its main role is to discuss about what was achieved in the sprint. The Scrum Master ensures that the event takes place and that everyone understand its usage.
The Sprint Review includes the following elements:
The Sprint Retrospective occurs after the Sprint Review and before the next sprint planning. Its goal is to allow the scrum team to create a plan for improvements for the next sprint.
Kanban is an approach that uses kanban board to visualize the status of the work.
                                            Kanban board is a work and workflow visualization tool that allow the developers to keep track of their team’s actual work status by communicating its progress and / or the issues encountered.
How should you decide whether you should use a physical or a virtual board for your team?
A physical board usually uses sticky notes for the Kanban cards, and the board is drawn on a whiteboard or a wall.
This is a good approach for teams that are 100% on-site, since every team member can interact with the board directly.
A virtual board is usually required for teams that are split into more than one location. Another advantage that virtual boards have is that it provides additional collaboration features, like email integration or accessibility for remote workers.
Regardless of their state, Kanban boards allows for a full-view of the project / sprint state.
Test-driven Development (TDD)is a development technique where the developer must first write a test that fails, and then write just enough production code for the test to confirm it. This practice make sure that only the relevant code will reach the delivery, and it allows problems to be detected as soon as possible.
                                            In the context of testing, we should (at least) test Valid and Invalid inputs, errors and exceptions, and boundary conditions.
If you don’t think tests are useful, or if you think you don’t need tests – mind this – the tests are not only for you.
The tests are:
The tests exists to ease the refactoring and to assure that new code can be added without affecting the current implementation.
The beautiful thing with TDD is that you’ll always have a test available.
Do you know the feeling you get when you see some bad code, and you don’t want to change anything there, because you might break it ? And there’s no test that you can use to be sure that the functionality will still work afterwards?
TDD can also substitute the documentation. I know, you haven’t signed up for that. Who wants to write documentation ? Well, I do. And so does your manager.
But isn’t it less boring when the unit tests cover for documentation?
You STILL want more praise ?
Well, TDD follow the best coding practices, including SOLID, KISS, DRY, and YAGNI.
Therefore, you will not over-engineer things and you’ll write elegant code, which will be easy to maintain.
People will love you for that. Let’s see what’s all this fuss with TDD, then.
Test driven development consists of three phases; Red, Green, and Refactor.
In this phase, we need to write a test for the functionality we will implement.
How can we write a test for something that doesn’t exist?
First, we create the interface (or a class that contains only the name of the methods, without implementation), and then we write a test for the input-output set – which will obviously fail.
This is useful because:
Here, we do what we do best – we write code.
We need to write enough code to pass the test. Good, bad, ugly, we have to make the test pass first.
It’s working? Don’t touch it. Wait, no, that doesn’t belong here.
Absolutely touch it now. Modify the code and keep the tests green.
Rename the function and variable names, reduce dependencies, improve performance, refactor as much as you’d like, but make sure that you check the tests after each small change – you don’t want to change 100 lines of code or more and then realise the tests don’t pass anymore.
Behaviour-driven development (BDD) is an approach that evolved from TDD, and it focuses on tests which describe behaviour, rather than tests which test a unit of implementation.
The difference between these two is that the BDD is written in a common language (English) so that both tech and non-tech teams will understand it.
                                            The BDD cycle is identical with the TDD one, except the first step (Write a failing test) which is done by a developer, is replaced with “Write a specification”, which can be done by a non-technical person.
In order to use BDD, the team will need to have prior experience with TDD.
Another disadvantage would be that we need to have properly specified requirements.
On the bright side, BDD allows for a better communication between everyone involved (software developers, software testers, stakeholders), and can reach a wider audience due to its non-technical approach.
After the scenarios are set, they can also be further used as Acceptance Criteria by the customer, and the software testers can use those scenarios as the basis for their tests.
The formula proposed for BDD is the ‘Given-When-Then’: Given a certain scenario, When an action takes place, Then the outcome shall be the following:
                                        Given the user presses the login button without password set
                                        When they click on login
                                        Then an error message should be shown
Another template for BDD is the Role-Feature-Reason:
                                        As a user,
                                        I want to click on the login button without having password set,
                                        So that an error message will be displayed.
We’ve talked about TDD, which is performed by the developer alone.
We’ve talked about BDD, which involves non-technical people to discuss with the technical team regarding scenarios and how the software should behave under different conditions.
Domain Driven Design is a way of communication which involves both the software developers and the experts in the given domain we write the software for.
                                            As developers, our job is to solve problems through software, and coding is only one aspect of software development.
Before being able to solve a problem, we first need to understand it properly - and a way of finding out what the software should do is to discuss about it directly with the people that need it.
The meeting includes both technical and non-technical people, so UML diagrams or similar should be used to provide understandable context for everyone involved.
DDD emphasizes on understanding the problem domain, and on providing guidelines for how the system should be created so that the needs of the people that are using it will be fulfilled.
Through DDD, we will be able to have a top-level architecture, we will know what are the expectations in terms of functionality, it reduces the misunderstandings between domain experts and the architects, and reduces the change requests coming from the client.
Stakeholders: People involved / interested in the topic, that have influence or power over it.
KISS (Keep it simple, stupid), DRY (don’t repeat yourself), YAGNI (you aren’t gonna need it).
Acceptance criteria – conditions that a software must satisfy to be accepted by the user/customer.
Appendix B contain a list of behavior questions.
Appendix C contains a list of questions that the candidate may ask regarding the company.
Will be discussed in detail in Architecture chapter, Quality attributes.
Performance is the ability of the system to execute actions within a certain period of time.
Availability is the ability of the system to be fully or partly operational.
Will be discussed in detail in Architecture chapter, Quality attributes.
Security is the ability of an application to be secure.
Usability refers to how easy it is to use or to learn the application.
Security is the ability of an application to be secure.
Usability refers to how easy it is to use or to learn the application.