# Language-Integrated Query

## Summary

SQL databases, XML documents, web services and data objects are examples of different types of data sources. Each of these is typically interfaced differently from application code. LINQ simplifies this by offering a single unified querying capability directly within the C# language. In other words, querying is a first-class language construct.

Code using LINQ is simpler and concise. Syntax and type checking are possible at compile time along with IntelliSense support. This is unlike database interfacing in which queries are treated as strings. Debugging LINQ queries is easier.

.NET's Entity Framework Core is the modern way of using LINQ. LINQ is available in C#, F# and Visual Basic. In C#, SQL Server databases, XML documents, ADO.NET Datasets and collections with `IEnumerable` or `IEnumerable<T>` interfaces are supported. Third-party tools are available for interfacing LINQ with web services and other databases.

## Discussion

### Could you explain LINQ with a simple example?

`Doctors` collection inherits from `List<Doctor>`. Suppose we wish to know all doctors in Chicago. A common programming approach is to loop through the collection, check for a condition (Chicago, in our example) and store the matches into another collection.

LINQ provides a **declarative syntax** that's more like querying an SQL database. With LINQ and other .NET features, we can do many things with ease: find doctors in Chicago (filtering), sort doctors by their pager number (sorting), count the number of doctors in each city (grouping and counting), change specific attributes (updating), add a new doctor (inserting), etc.

Though LINQ doesn't directly support CRUD (Create, Read, Update, Delete), it supports CRUD-like operations and does so in a more intuitive manner. Such queries and transforms are first-class concepts of C#. Here are some examples (note that `Add()` and `RemoveAll()` are methods of `List<T>`):

    + Create: `doctors.Add( new Doctor("John", "Smith", ... ) );`
    + Read: `var larsens = from d in doctors where d.FamilyLastName == "Larsen" select d;`
    + Update: `foreach (var d in larsens) d.City = "Suburb";`
    + Delete: `doctors.RemoveAll(x => x.FamilyLastName == "Larsen");`

### What's the architecture of LINQ in .NET?

.NET LINQ provides programmers a single unified API to interact with various types of data sources. These can be in-memory data structures/objects, XML documents, databases, and more. LINQ queries are translated into data source operations by what's called a **LINQ provider**. Developers can write their own LINQ providers to interface to data sources not supported by default in .NET.

Among the built-in providers are LINQ to Objects, LINQ to XML, LINQ to DataSet, LINQ to SQL, and LINQ to Entities. **LINQ to SQL** enables developers to generate .NET classes that interface to relational databases directly. **LINQ to Entities** provides an alternative so that applications interact with data as objects. LINQ support is at this object layer. The Entity Data Model presents a conceptual model that represents the data. It's been said that LINQ to SQL was .NET's first attempt at an ORM with support for only SQL Server. LINQ to Entities is the more modern approach.

There are many more third-party LINQ providers to query various data sources such as search engines (Google, Bing), spreadsheets (CSV, Excel), APIs (Twitter, MediaWiki), etc.

### What programming languages support LINQ?

LINQ is supported in C#, F# and Visual Basic. There's little difference between using LINQ in C# and F#. Moreover, LINQ queries can be expressed differently using F# built-in functions. Between C# and Visual Basic, there are some syntax differences.

Other languages have tried to adopt LINQ-like capabilities. *PHPLinq* is an example with a syntax such as `from('$name')->in($names)->where('$name => strlen($name) < 5')->select('$name')`. This relies on lambda expressions. However, query expressions are quoted and therefore just strings. They don't benefit from the real power of LINQ.

*Elcy* is an ORM for TypeScript/JavaScript with LINQ-like query syntax. Another JavaScript library is *Underscore.js*, which adopts the functional programming paradigm.

Indeed, while LINQ is declarative it has similarities with functional programming. Mukherjee's book *Thinking in LINQ* teaches how LINQ can enable functional programming. Python's *toolz* and Ruby's *Enumerable* are packages that come to close to LINQ.

### How does LINQ's query syntax differ from it's method syntax?

LINQ's **query syntax** is similar to that in SQL. The simple example in the figure shows the `from-in` construct, a conditional expression and query operators. These together make a *query expression*. In LINQ's **method syntax**, operations appear as methods that are called on the data source. Method calls are chained. Both are equivalent and have similar performance. In fact, queries are transformed into methods before being compiled. Lambda expressions are typical of the method syntax.

Query syntax is more readable. Intermediate variables using the `let` keyword can be created with query syntax. However, operations that return singleton numeric values (such as `Min`, `Sum`, etc.) must use the method syntax. It's also permitted to mix the two syntaxes, that is, a query expression enclosed in parentheses and followed by a method call. An example is `(from num in numbers where num < 3 select num).Count()`.

Both syntaxes result in a query object that's typically a collection of type `IEnumerable<T>`. The query object doesn't contain the results. Results are produced only when the query is executed.

### What is deferred execution in LINQ?

When a query object is returned, it's not immediately executed. If it interfaces to an external data source, the data source is not immediately contacted. This happens only when the query is executed and results are needed. This is what we mean by **deferred execution** in LINQ (aka lazy evaluation). When a query object is used within a `foreach` loop, then the query is executed. Another way to trigger deferred execution is to call the `GetEnumerator()` method.

Within deferred execution, some LINQ operators support streaming. With **streaming**, the entire source data is not read at once. Results are returned when needed. With **non-streaming**, all source data is read before the results are returned. Sorting and grouping are examples of non-streaming operations. Some streaming operators have two input sequences where the first sequence is evaluated in a deferred streaming manner and the second in a deferred non-streaming manner. Examples include `Except`, `GroupJoin`, `Intersect` and `Join`.

For **immediate execution** we call `Enumerable.ToList()` or `Enumerable.ToArray()` on the results. Another way to trigger immediate execution is to call some functions, such as `Count()`, `Max()` and `Average()`.

### What are some operations that LINQ can perform?

.NET documentation gives a complete table of LINQ operators and their support for deferred/immediate execution.

LINQ query operators can be classified into aggregate (`Average`, `Count`, `Sum`), set (`Distinct`, `Except`, `Intersect`, `Union`), concatenation (`Concat`), join (`Join`), conversion (`AsEnumerable`, `Cast`, `OfType`, `ToArray`, `ToList`), element (`ElementAt`, `First`, `FirstOrDefault`, `Last`, `Single`), equality (`SequenceEqual`), generation (`Empty`, `Range`, `Repeat`), ordering (`OrderBy`, `ThenByDescending`), partitioning (`Skip`, `TakeWhile`), projection (`Select`, `SelectMany`, `Zip`), quantifier (`All`, `Any`), and restriction/filtering (`Where`).

Third-party packages are available that extend the above built-in LINQ operations. One such example is MoreLINQ.

### How does LINQ handle data types?

All variables in a query expression are **strongly typed**. Type can be declared explicitly but the compiler is smart enough to infer the type in many cases.

Consider `var custQuery = from cust in Customers where cust.City == "London" select cust`. The use of `var` implies type inference. There's no need to explicitly declare it with `IEnumerable<Customer>`. Another example where `var` makes sense is when an anonymous type is returned. Example, `var query = from cust in Customers where cust.City == "London" select new { name = cust.Name, phone = cust.Phone }`.

When non-generic `IEnumerable` collections such as `ArrayList` are queried, type must be explicit, at least in the `from` expression. Example, `var query = from Student s in students`.

`IEnumerable<T>` queries are compiled to delegates. `IQueryable` and `IQueryable<T>` queries are compiled to expression trees. For example, LINQ to Objects works with delegates. LINQ to SQL works with expression trees. An **expression tree** is a data structure that defines code.

### What are some tips when using LINQ?

To check if a collection has items (that optionally match a specific condition), prefer to use `Any()` rather than `Count()`. Prefer to use `Any(condition)` instead of `Where(condition).Any()`. When calling `FirstOrDefault()`, check for null object reference before using the returned result. Alternatively, include the method `DefaultIfEmpty()` in the query to specify a default value.

A query such as `from c in db.Customers select c` does nothing. Instead simply say `db.Customers`. Likewise, `(from c in db.Customers where c.ID == 123 select c).Single()` can be simplified to `db.Customers.Single(c => c.ID == 123)`.

Unlike SQL, joins can be accomplished without using the `join` keyword. This is due to LINQ's association properties. Thus, to obtain customers who haven't purchased anything, we can simply write `from c in db.Customers where !c.Purchases.Any() select new { c.ID, c.Name }`.

Although SQL emits flat result sets, LINQ can return complex objects. Such objects are easily initialized within either anonymous types or named types. With the latter, such types can be returned from methods.

Since query execution is deferred, queries can be built in steps. This makes the code more readable and maintainable.

### What are some limitations of LINQ?

There are two sides to LINQ: consumers and implementers. For consumers, LINQ brings many benefits. For implementers, writing a LINQ provider is not easy. Essentially, this involves implementing `IQueryable<T>` that reads an expression tree and figure out how to translate that to query the underlying data store.

LINQ allows consumers to write queries, some of which may not execute efficiently at the database layer. The semantics of LINQ that are well-suited for memory collections may not map very well to relational and non-relational databases. Thus, it's possible to have queries that a LINQ provider may fail to handle properly.

It's been said that LINQ is not suited for complex SQL queries. SQL store procedures have execution caching that the LINQ approach can't utilize.

### Where can I learn more about LINQ?

Official .NET documentation describes how to use LINQ in C# and LINQ in Visual Basic. An important reference is the System.Linq namespace documentation.

Microsoft has published some videos that explain LINQ. A repository called try-samples has some LINQ examples.

Among the books to read are *C# 10 Pocket Reference* and *LINQ Pocket Reference* by Albahari and Albahari.

There are many useful tools that improve the developer experience when working with LINQ:

    + **Visual Studio IDE**: This supports IntelliSense and syntax highlighting of LINQ queries. The debugger can debug query expressions. As a visual tool, there's *Object Relational Designer* for LINQ to SQL applications. CLI tool *SQLMetal* can generate classes from databases.
    + **LINQ Insight**: Allows developers to execute, debug and analyze queries during the design phase even without starting a debug session.
    + **LINQPad**: Similar to LINQ Insight. Can also execute C#/F#/VB code snippets. A related tool is *LINQPad.QueryPlanVisualizer* that supports SQL Server and PostgreSQL for databases, and Entity Framework Core 5 and LINQ to SQL for ORMs.

## Milestones

1995

Buneman et al. publish a paper titled *Principles of programming with complex objects and collection types*. While not directly related to LINQ, this paper shares the theoretical foundations. In particular, relational algebra and category theory (monads) are used.

2004

The idea of using "sequence operators" that can be used on any `IEnumerable` collection is proposed by Anders Hejlsberg, the chief designer of C#. Such operators can also be used for remote queries on `IQueryable` types. The compiler needs to know about such operators so that correct static methods and delegates can be called.

2006

Meijer et al. note the problem of ROX impedance mismatch, where ROX (Relational, Object, XML) relates to data access technologies. .NET Framework's upcoming release is meant to solve this problem via LINQ. The LINQ framework would define two domain-specific APIs: **XLinq** (for XML documents) and **DLinq** (for relational data).

Nov
2007

Microsoft releases .NET Framework 3.5. **LINQ** is added as part of this release.

Aug
2008

Microsoft releases .NET Framework 3.5 Service Pack 1. This includes **ADO.NET Entity Framework** and **ADO.NET Data Services**. This enables LINQ to query databases with strong typing. In later years, it's claimed that LINQ changed how programmers write C# code.

Apr
2010

Microsoft releases .NET Framework 4.0. This includes support for parallel computing (multi-core or distributed systems). To this end, **Parallel LINQ (PLINQ)** is added. PLINQ bring parallelism to LINQ.

2013

Cheney et al. publish a paper titled *A Practical Theory of Language-Integrated Query*. Their approach uses quotation and normalization. Their theory is called **T-LINQ**. They provide an implementation in F# called **P-LINQ**. They note that Microsoft's LINQ fails for some of their example queries whereas P-LINQ works correctly.

Nov
2021

Microsoft releases .NET 6. This release expands the LINQ API in many ways. The `Enumerable` class gets many new methods: `TryGetNonEnumeratedCount` for counting without enumerating, `DistinctBy`/`UnionBy`/`IntersectBy`/`ExceptBy` for set operations with specific selector functions, `MaxBy`/`MinBy` operations with selector functions, `Chunk` for chunking, `FirstOrDefault`/`LastOrDefault`/`SingleOrDefault` to return defaults on empty enumerables, and more. `Zip` can now do three-way combines. `ElementAt` can take indices from the end.

Nov
2022

Microsoft releases .NET 7. With SQL Server's **JSON support**, LINQ can now query JSON documents stored in a relational database.  There's now a simpler way to order items, using `Order` rather than `OrderBy`, The latter method is still useful for ordering non-trivial objects that don't implement `IComparable<T>`.

Language-Integrated Query


# Python OOP

## Summary

Python is an Object-Oriented Programming (OOP) language. Many OOP concepts are available in Python including classes, objects, (multiple) inheritance, polymorphism, and encapsulation.  Functions are also objects in Python. Data hiding in terms of access modifiers is not strict: class and instance attributes are public and private membership is not strictly enforced.

Apart from instance methods, class methods and static methods are possible. Abstract classes are possible and they're equivalent to interfaces in other languages. Implementations of these typically employ decorators. Nested functions and nested classes are supported.  What's called operator overloading in OOP is implemented using magic methods.

Since its beginning, Python support for OOP has continued to evolve. The aim has been to balance a simple intuitive syntax with features and performance desired by developers.

## Discussion

### What are some essential terms in Python OOP?

Here are a few essentials terms in Python OOP:

    + **Class**: Bundles data and functionality together. Acts as a template or factory for creating new instances.
    + **Instance**: Created from a class. We say an instance's type is the class from which it's created. Eg. `point` is an instance of `Point` given that `point = Point()`. Many instances of a class can be created.
    + **Attribute**: Relevant to both classes and instances. Accessed using the dot notation `obj.name`. Attributes are either data attributes (eg. `point.x`) or methods (eg. `point.move_left(5)`).
    + **Method**: Belongs to an object. It's called to execute the code it contains. Note that `point.move_left` returns a *method object* whereas `Point.move_left` returns a *function object*.Instances are also called *objects*. Strictly speaking, we distinguish two types of objects:

    + **Class Object**: Nothing more than a wrapper around the namespace created by the class definition. There are two things we can do with a class object: access its attributes or instantiate a new instance.
    + **Instance Object**: This is an instance created from a class. The only thing we can do with an instance object is to access its attributes.

### How do I define classes and instantiate objects in Python?

A class of name 'Foo' can be defined with `class Foo: pass`, where `class` is a Python keyword. An instance or object of this class can be created with `foo = Foo()`, where `foo` is an instance of the `Foo` class.

Every Python class inherits from `object`. It's the base for all classes. It doesn't accept any arguments. It's also featureless, that is, we can't assign attributes to instances of `object`.

A class `Rectangle` that inherits from another class `Shape` can be defined as `def Rectangle(Shape): pass`. **Multi-level inheritance** is also supported, such as, `def Square(Rectangle): pass`. **Multiple inheritance**, which is the ability of a class to inherit from multiple class, is also supported. For example, we can design a `Novel` class that inherits from two classes `Book` and `Fiction`: `def Novel(Book, Fiction)`. The order of the base classes is significant.

Unlike `foo` in the earlier example we can create classes that are initialized with arguments. For example, `corner = Point(1.3, -2.4)` creates a `Point` object named `corner` that's initialized with (x=1.3, y=-2.4) coordinates.

### What's the lifecycle of a Python object?

When instantiated from its class definition, a Python object is created (memory is allocated) and then initialized. The object is stored in memory and accessible by the program. When the object is no longer required, it's destroyed and its memory is reclaimed by the system.

The following class methods are relevant to a Python object's lifecycle:

    + `__new__`: Called automatically to instantiate an object. A developer rarely needs to customize the default implementation of this method.
    + `__init__`: Called automatically after `__new__` for initializing the object. Can accept arguments, such as, `def __init__(self, x, y)` of a `Point` class to initialize it's attributes.
    + `__del__`: Called automatically when the object is destroyed. A programmer can explicitly destroy the object by calling the `del()` built-in function or leave it to Python's garbage collector to do it. Either way, `__del__` is called. If the interpreter exits, there's no guarantee that `__del__` is called for existing instances.

### What's the naming convention for Python class definitions?

Python PEP 8 describes the naming convention and styling to be followed by developers. The following are relevant to class definitions:

    + Surround top-level function and class definitions with two blank lines.
    + Method definitions inside a class are surrounded by a single blank line.
    + Write docstrings for all public modules, functions, classes, and methods.
    + `single_trailing_underscore_` argument name: avoids conflict with Python keywords. Eg. `register_student(self, class_, section)`.
    + `__double_leading_underscore` attribute name: kind of private and avoids conflicts with subclasses. Invokes Python's name mangling rules.
    + `__double_leading_and_trailing_underscore__` name: convention is reserved for magic methods or other special uses. Don't name your attributes this way.
    + Class names should normally use the CapWords convention.
    + Class naming applies to Exceptions since they're also classes. Use the suffix "Error" in exception names.
    + Always use `self` for the first argument to instance methods.
    + Always use `cls` for the first argument to class methods.
    + For variable annotations, use single space after colon and no space before colon. Eg. `coords: Tuple[int, int]`.

### What are nested functions and nested classes in Python?

We typically define functions at module level. But it's possible to define a function within another function. For example, `def g(): pass` can be defined within the body of another function `f()`. Function `g` is therefore a **nested function**. It can't be invoked from outside its container function. It can be invoked only by `f`. Nested functions are therefore useful to implement encapsulation. For example, function `get_projection` is defined within function `get_area` but how the projection is calculated is particular to the area calculation. Therefore, we don't want others to use the projection.

It's possible for a nested function to be returned from its container function. In this case, the returned function can be called from outside. In fact, partial functions and closures are implemented this way.

Like nested functions, for better encapsulation but at the expense of code reuse, a class can be defined within another class. The former is therefore a **nested class**. The outer class may instantiate objects of its inner classes. An inner class can be instantiated without instantiating its outer class.

### What are magic methods in Python OOP?

Magic methods, also called *dunder methods*, are special methods that are typically not explicitly called in application code. The Python interpreter calls them depending on the operation currently requested by the program.

For example, `__new__` and `__init__` are magic methods called respectively for creating and initializing an instance from its class. When we compare two objects (`a == b`), magic method `__eq__` is called on one object with the other object passed in as an argument. When we call `del()` method on an attribute, magic method `__delattr__` is called. To add two objects (`a + b`), magic method `__add__` is called.

We may say that magic methods dictate what happens under the hood. They're useful when defining custom classes and we wish to override default behaviour. Custom classes can emulate the behaviour of built-in types. For example, we may define a custom string class derived from `str` built-in class. By overriding `__eq__`, we can enable case-insensitive comparison of strings.

All magic methods are named with leading and trailing double underscores. Other methods should not be named this way.

### Could you compare a Python object's static methods and class methods?

When an instance is created, its methods are called instance methods. An instance method takes in `self` as the first argument. This points to that particular instance. Via this argument, the method can access all other attributes of the instance.

There are some methods that don't need the instance. They operate purely on the input arguments and output a result. They don't read or change state of the instance. These are called **static methods** and are defined via the `@staticmethod` decorator. In one use case, static methods could be helper functions that assist instance methods in their computations. They could also be called from outside the class.

While each instance has its own state, we might need all instances share some attributes. For example, multiple instances of a `Logger` class log to the same file. Filename could be a shared state. Shared attributes are defined as class attributes rather than instance attributes. Methods that operate only on class attributes are called **class methods** and are defined via the `@classmethod` operator. A class method takes in `cls` as the first argument.

### How do I define private or protected class attributes in Python?

Class and instance attributes are public. However, by naming convention, some developers treat attributes that start with a single underscore as protected. That is, only subclasses can access base class attributes. Others use single underscore to imply non-public access. The language itself offers no protection against public access.

Another convention is to name attributes starting with double underscores. Such attributes are private to the class. In reality, Python does **name mangling**. It renames the attribute so that it becomes inaccessible from outside the class under its original name. However, within the class, the original name is valid. As an example, attribute `__update` in class `Mapping` will become `_Mapping__update`.

Even with name mangling, a persistent developer can still access the attribute from outside the class by using the mangled name. In conclusion, Python's support for private attributes is not strict. Name mangling does solve the problem of conflicting names due to subclass attributes.

### What's Method Resolution Order (MRO) in Python?

Consider `Novel` class that inherits from two classes `Book` and `Fiction`: `def Novel(Book, Fiction)`. If both `Book` and `Fiction` implement the method `get_title()` but `Novel` doesn't override this method, MRO determines which one gets called. Python adopts **C3 MRO algorithm**. Essentially, it says that method calls are resolved depth first but where a common ancestor is involved, it is called as late as possible.

In the above `Novel` example, `Book.get_title()` is called. But let's consider a more complex example shown in the figure. Method call on a `Romantic19Novel` instance resolves to `RomanticNovel` and then `Novel` (depth first rule). However, `Novel` is also a base class of `NineteenthCenturyNovel`. Hence, `Novel` is deferred until later. Thus, the MRO is (`Romantic19Novel`, `RomanticNovel`, `NineteenthCenturyNovel`, `Novel`, `Book`, `object`).

Given any class, we can introspect the MRO by calling the `mro()` method, or accessing the `__mro__` attribute. Eg. `Romantic19Novel.mro()`. Note that these can't be called on instances.

While C3 MRO algorithm works in most cases, sometimes it's unable to resolve. In such a case, Python interpreter will raise an exception and fail to even define the class.

### What is cooperative multiple inheritance in Python?

It's possible to implement our methods in such a way that MRO becomes easier. Even if the order of base classes were changed in the case of multiple inheritance, we would still achieve consistent runtime behaviour. Cooperative multiple inheritance also makes it easier to inject new classes into the inheritance hierarchy.

Implementing methods cooperatively means fulfilling the following three conditions:

    + Every implementation of the method need to call `super()`.
    + The method being called by `super()`needs to exist.
    + The caller and called base class methods have matching argument signatures. In particular, they accept `**kwargs` keyword arguments dictionary as the last argument. A method will strip any keyword argument it requires and pass on the rest to its immediate base class via `**kwargs`.

## Milestones

Jan
1994

Python 1.0 is released. This version includes support for **classes and inheritance**, which were also present in earlier version 0.9.

Dec
2001

Python 2.2 is released. Via PEP 252 and 253, this release **unifies built-in types and user-defined classes**. We can now subclass built-in types. We can define **static methods** and **class methods**. We also have **properties** to automatically call methods when accessing or setting instance attributes. The introspection API is now unified across types and classes. Despite being a big change, this is done with backwards compatibility. Python 2.1 and earlier are now known as "classic Python" and classes without built-in types in their bases are called "classic classes".

Jul
2003

Python 2.3 is released. This version changes the Method Resolution Order (MRO). Specifically, it adopts **C3 MRO** that was invented back in 1996 for the Dylan programming language. Even with C3, there are some complex inheritance hierarchies where its impossible to resolve the order and Python raises an exception.

Nov
2004

Python 2.4 is released. Via PEP 318, this release includes **decorators for functions and methods**. Wrappers `staticmethod()` and `classmethod()` available since Python 2.2 are now available as decorators `@staticmethod` and `@classmethod`. **Class decorators** are introduced in Python 3.0 (Dec 2008) via PEP 3129.

Apr
2007

PEP 3119 is created to introduce **Abstract Base Class (ABC)** into the language. ABCs are conceptually close to what other languages call interfaces. In fact, back in 2001, PEP 245 considered introducing interfaces but the proposal was rejected. In December 2008, ABCs become part of Python 3.0 release and also backported to Python 2.6.

Dec
2008

Python 3.0 is released. Via PEP 3135, this release allows `super()` to be called without arguments to invoke methods. For example, the syntax `super(Foo, self).foo(1, 2)` is simplified to `super().foo(1, 2)`. The word `super` itself is not reserved and is interpreted specially only within the context of a method definition. This release also **gets rid of unbound methods**. Accessing a method as class attribute now results in a plain function object.

Sep
2012

Python 3.3 is released. Via PEP 3155, this release adds **qualified name** attribute `__qualname__` to classes and functions. This enhances introspection for nested classes and functions. The qualified name also helps in Python3 since there's no `im_class` attribute (unbound methods in Python2).

Python OOP


# Vue.js

## Summary

Vue.js is a lightweight frontend JavaScript framework. It can be used to develop modular UI components or entire Single Page Applications (SPAs). It features an incrementally adoptable architecture that focuses on declarative rendering and component composition. Advanced features such as routing, state management, build tooling, animations, and validations are offered via officially maintained libraries and packages.

If you know HTML, CSS, and JS, it's easy to get started with Vue.js. Because of it's lean design, it takes up only a few tens of kilobytes. It's fast. It's open source and community led. It integrates well with other tools. It's also being used to build mobile apps.

## Discussion

### What's the benefit of using Vue.js over vanilla JavaScript?

JavaScript enabled us to add more dynamic content to web pages plus have rich user interactions. With vanilla JS, this came with increased code complexity and low maintainability. For example, to add interactions we would need to link event handlers to DOM elements, code these handlers (using vanilla JS or jQuery for example), make AJAX calls, handle the responses and update DOM elements. All this was done using hand-crafted code that was difficult to scale and maintain for large projects.

It's to solve this problem that JavaScript frameworks were introduced. Vue.js is one of them, with Angular and React being alternatives. Vue.js is said to be approachable, versatile and performant.

Vue.js is a **progressive JS framework**. This means that you're not forced to migrate your entire app at once. Instead, you can incrementally migrate some components that need rich interactions. Vue.js plays well with other code. You can use Vue.js code in apps written in other frameworks and also embed other code inside of Vue.js.

### Who's using Vue and what's been their experience?

In 2017, Vue.js was named the "most willingly learned technology". Companies of all sizes and market domains have adopted Vue.js. This includes Netflix, Facebook, Alibaba, Adobe, Xiaomi, Grammarly, Laracasts, Behance, GitLab, 9gag, Nintendo, Chess, and Font Awesome.

Made With Vue.js showcases lots of projects developed using Vue.js. These include components, frameworks, webapps, websites, games, and more.

A survey of 1,553 responses collected in Nov-Dec 2018 showed that 92% would use Vue.js for their next project. 75% saw ease of integration as the biggest advantage and 58% found it easy to learn and apply. More than half saw documentation, performance and progressiveness as important advantages.

### How does Vue.js compare against other frontend development frameworks?

The common parameters for comparing various frontend frameworks are features, documentation, developer tooling, adoption, third-party libraries, and community support. While React and Angular are led by Facebook and Google respectively, Vue.js is more community led, though there's a core team to set roadmaps.

For building complex apps, other frameworks such as Ember and Angular provide an opinionated set of components. Vue.js core instead focuses on data binding, similar to React. Outside the core functionality, React leaves everything to the community. This creates churn, with developers not sure what to adopt. Vue.js takes the middle path where the core exposes minimal features and other official libraries offer incrementally adoptable pieces; but developers are not tied to using them. Thus, it's more approachable that React.

It's been said that for migrating AngularJS (not Angular) apps, Vue.js is a natural fit mainly due to similar templating syntax and reactive model. In incremental migration, Vue.js and AngularJS play nicely with each other.

Vue.js is about 80KB while React is 100KB and Angular is 500KB. Hacker Noon offers a detailed comparison of the three frameworks.

### What are the main features of Vue.js?

Vue essentially extends HTML with **components**. These are custom elements to which Vue compiler attaches behaviour and binds data. Vue uses **templates** that are compiled to virtual DOM render functions.

A Vue component also has **scripts** for defining local data, props, computed properties, watchers, methods, and lifecycle hooks. We can also include component specific **styles** that are scoped to the component. CSS styling can also use pre-processors such as Less or SCSS. When data changes, CSS transitions and animations can be easily coded with Vue.

Vue adopts the ViewModel part of the Model-View-ViewModel (MVVM) architecture. However, developers can adopt Flux architecture, as is usually the case when using Vuex for state management.

We can use props to pass data down to components. To inform a parent component that some data has changed, use `$emit` events. For more complex communication, use **EventBus** (for small apps) or **Vuex** (for large apps).

Other useful features are built-in modifiers, mixins, plugins, filters, JSX, and custom directives.

### What's the Vue.js component lifecycle?

A Vue.js component moves through different states in it's lifetime: created, mounted, updated, destroyed. These states are associated with a number of **lifecycle hooks** that we can use to execute custom JS code.

Just after a Vue component is instantiated, `beforeCreate()` is called. At this point, component has no access to the data model. Once created, the `created()` hook is called, which is a good place to load any data. Now, the component is ready to watch data for changes and listen for events.

However, the component is still isolated from view layer (the native DOM) and nothing will be displayed. Vue will display the data only when component's mounted. Hooks relevant in this phase are `beforeMount()` and `mounted()`. Once mounted, we can access the `$el` property that helps us update the DOM when necessary.

Once mounted, an update cycle is started whenever data is updated. Virtual DOM is updated and differences are patched to the native DOM for efficient rendering. Relevant hooks are `beforeUpdate()` and `updated()`.

When component is not longer required in the DOM and being destroyed, we can use hooks `beforeDestroyed()` and `destroyed()`.

### How is the ecosystem around the core of Vue.js?

The Vue team maintains the Vue.js core that focuses on the view layer. They also maintain other libraries that help you build rich single page applications:

    + **vue-router**: For SPA routing.
    + **vuex**: For large-scale state management.
    + **vue-cli**: To create project scaffolding.
    + **vue-loader**: A loader for webpack. This is useful for Vue components in a format called *Single-File Component* (SFC), which is a `*.vue` file.
    + **vue-class-component**: TypeScript decorator for a class-based API.
    + **vue-rx**: RxJS integration.
    + **vue-devtools**: Browser DevTools extension. This can be a Chrome extension, Firefox addon or standalone Electron app.
    + **vue-test-utils**: For unit testing.
    + **vue-server-renderer**: For building isomorphic or universal JS apps, with app code running on both server and client. As an alternative, there's Nuxt.js, just as React has Next.js.

### Which are some third-party libraries and tools for Vue developers?

Here are some third-party tools that might interest developers:

    + **vue-templates**: Out-of-the-box templates to avoid manual config and boilerplate.
    + **vue-dummy**: For placeholder text and images.
    + **VuePress**: Static site generator.
    + **Gridsome**: Framework for static sites with GraphQL for data management.
    + **Vuetify**: UI component library based on Material Design.
    + **Quasar**: Framework that enables single codebase for SPAs, PWAs, hybrid mobile apps, desktop apps, etc.
    + **Storybook**: For writing UI components and target multiple frontend frameworks.
    + **Vue Apollo**: Integrate Vue with GraphQL.
    + **Weex**: Framework for building mobile apps with Vue and others.
    + **Bit**: To organize and share components across apps.
    + **Vue Starter**: Boilerplate for production-ready PWAs.
    + **Vue Design System**: A set of tools, patterns, and practices for building UI design systems.
    + **VS Code / Atom Integration**: Vue-related extensions for VS Code and Atom editors, to name just a couple.

### Could you share some tips and best practices for using Vue.js?

When you reuse components across views, new Vue instances won't be instantiated. Instead, use a custom handler to react to route changes. Avoid manipulating the DOM directly. Instead use `$refs`. Use computed properties to manipulate component data. These are also cached from their reactive dependencies. Validate your props.

Here are some tips for better performance:

    + **Loop Items**: Use `:key` so that Vue can update items more efficiently.
    + **Functional Components**: Cheaper than stateful components. Use these if you're only accepting props and rendering markup.
    + **Component Registration**: Avoid registering all components globally. Import specific components within other components, preferably asynchronously.
    + **Code Splitting**: Split your code into logical parts to reduce JS bundle size. Enables lazy loading.
    + **Lazy Loading**: For local component registration, route declaration and other stuff not needed upfront. Load components as necessary based on user actions.
    + **SVG**: Hide/show elements rather than frequently removing or adding them. A faster alternative to SVG is to use Canvas and WebGL, which are not XML based.

### What are some criticisms or concerns with Vue.js?

Traditionally, Vue.js was not suited for building mobile apps. This is changing. Vue's founder, Evan You, commented in March 2019 that Vue.js is already "unofficially" supporting integration with NativeScript, Quasar and Ionic 4.

### What are some useful resources for a beginner to learn Vue.js?

A good place to start learning Vue.js is to read the official guide. A series of Vue videos on Laracasts is worth studying. Vue Mastery is another useful resource with lots of Vue lessons.

For building SPAs, read Bland's tutorial or Chuchin's tutorial. For building PWAs, read Rajat's tutorial.

For reference, Vue Mastery has released a handy cheat sheet. For ready-to-use themes, Creative Time provides UI kits, templates and dashboards based on Vue.js.

For latest news, follow The Vue Point, the official Vue.js blog.

Developers who wish to contribute, should head to the Vue.js page on GitHub.

## Milestones

2013

Evan You at Google Creative Lab starts experimenting with the good parts of Angular, especially it's declarative data binding. He feels that for simple use cases Angular is too heavy and opinionated. It's from here that he creates and names **Vue.js**.

Feb
2014

Evan You releases Vue code on GitHub and shares a link on Hacker News. The project gets several hundred stars within the first week. The actual version is **Vue 0.9.0 Animatrix**. Since then, Vue releases are code named based on anime names.

Oct
2015

**Version 1.0.0 Evangelion** is released after 300+ commits, 8 alphas, 4 betas and 2 release candidates. API is cleaned up to suit large projects, keeping in mind maintainability and refactoring. For fast initial rendering, `v-repeat` is replaced with `v-for`. Apart from the core, vue-loader, vueify and vue-router now provide a good foundation to build Single Page Applications. Also supported are hot component reloading and scoped CSS.

Sep
2016

**Version 2.0.0 Ghost in the Shell** is released. Work on this version started in April. This release includes TypeScript typings and superior rendering performance compared to Vue 1.0. Server-side rendering is possible. There's JSX support via a Babel plugin. The runtime is only 16KB when minified and zipped.

Aug
2018

**Vue CLI 3.0** is released. It's a rewrite of the older version. The aim is to reduce configuration fatigue and make it easier to work with multiple tools. It provides a pre-configured build setup using Webpack. It supports ES2017 transpilation, polyfills injection, CSS pre-processors, and more. The CLI comes with beta version of a GUI. This deprecates the older `vue-cli` command.

2019

In February, **Vue 2.6.0 Macross** is released. Meanwhile, Evan You comments that Vue 3.0 is likely to be released in 2019. It's a rewrite that sees some internal parts becoming individual packages. TypeScript is being used for the new version. You may wish to view a video titled Vue.js in 2019 & Beyond.

Vue.js


# Raspberry Pi

## Summary

Raspberry Pi is a credit-card-sized single-board computer (SBC) designed in the UK. It was started with the idea of making computers affordable, accessible and fun to a new generation of programmers.

Since its first release in 2012, many variant models of the Pi have been released, from $5 to $35. By 2018, more than 20 million units of the Pi were sold.

Though it was conceived as an educational tool, Raspberry Pi has since been used for home automation, in industrial systems and even on the International Space Station. It's managed by the *Raspberry Pi Foundation*. The schematics are available but the board itself is not open hardware.

## Discussion

### What are some applications where Raspberry Pi is suitable?

It's ideal for beginners to learn about computers and programming. With Raspbian as the OS, Python and Scratch come by default. You can make music with Sonic Pi. Those interested in gaming, can play and even tweak Python-based games. You can setup a web server on the Pi. For scientific computing, start using Mathematica. The Pi can also handle streaming video, play audio/video or be used as a media centre.

It's also a good platform to learn electronics, interface to sensors and build IoT projects. Many have used it for home automation projects. The small form factor and lower power requirements of Pi Zero enable battery-powered applications, possibly in remote areas. It can be used as an IoT gateway. With the increasing need for edge processing and analytics, the Pi has been used for such purposes.

In general, while a microcontroller-based system (such as Arduino) is good at input/output, the Pi is more suitable for applications that require lot more data processing, involve media streaming, network with other devices, or manage multiple processes.

### What interfaces does a Raspberry Pi expose?

While some models remove some of these interfaces, the following are present on Pi 3 Model B+: 4 x USB 2.0, Gigabit Ethernet, HDMI, analogue audio/video 3.5mm jack, Camera Serial Interface (CSI), Display Serial Interface (DSI) and a 40-pin GPIO header. CSI can connect to a camera. DSI can connect to a touchscreen display. For wireless networking, there's 802.11ac, Bluetooth 4.2 and BLE.

GPIO header supports common digital interfaces: I2C, SPI and UART. There are 17 pins for GPIO. There's also an I2S interface for audio output. All GPIO run on 3.3V and can give maximum 20mA. Due to these interfaces, the Pi's being used for IoT and robotics applications.

One interface that the Pi lacks is Analog-to-Digital Converter (ADC). An external ADC must therefore be used to interface to analogue sensors. The Pi can also be expanded with **HAT (Hardware Attached on Top)** expansion boards.

### What hardware variants of the Raspberry Pi have been released to date?

There have been to date four generations of Raspberry Pi:

    + Gen1: Model B, Model A, Model B+, Model A+, Compute Module 1
    + Gen2: Pi 2 Model B, Pi Zero
    + Gen3: Pi 3 Model B, Pi 3 Model B+, Pi 3 Model A+, Pi Zero W, Pi Zero WH, Compute Module 3, Compute Module 3 Lite, Compute Module 3+
    + Gen4: Pi 4 Model B (1/2/4GB)Compute Module is for industrial applications.

Higher generation boards have faster CPU and more memory. In terms of form factor, cost and capability, in decreasing order are B, A and Zero models. The "plus" variants are better than the plain ones of that generation. Wireless connectivity was introduced for the first time in third generation models. Hence, both Pi Zero W and WH belong here.

SocialCompare gives a feature comparison of most variants. RasPi.TV gives a nice picture of all the boards.

### How does one go about setting up a Raspberry Pi?

Raspberry Pi is just the processing module. It offers a number of interfaces to connect peripherals. HDMI can be used to connect to a display monitor or TV screen. For older displays, there's an analogue video interface. USB ports can be use to connect mouse and keyboard.

Ethernet port is for a wired LAN connection. Otherwise, on-board Wi-Fi of Pi 3 models can be used to connect to a wireless LAN. With older models, a USB-based Wi-Fi dongle can be used instead.

There's a micro USB to power up the Pi. However, Pi won't do anything without an operating system and software to run it. These should be loaded into an SD card. Online instructions can guide you to prepare the SD card.

To use the Pi from your desktop/laptop, read about headless mode and VNC.

### How is the software support for Raspberry Pi?

Raspberry Pi needs an operating system (OS). The official OS supported by the Foundation is **Raspbian**, which is based on Debian Linux distribution. Some Linux-based alternatives are Ubuntu MATE, Snappy Ubuntu Core and RaspBSD. There's also Windows 10 IoT Core, Android Things, PiNet, Weather Station and IchigoJam Pi.

To use Pi as a media centre, we can use OpenELEC, LibreELEC or OSMC. RISC OS, developed in the 1980s for ARM processors, can be used. For those who prefer a command line interface, try Plan 9. To use Pi for gaming, try RetroPie, RecalBox, Lakka and PiPlay.

Many of these can be installed using the **NOOBS** installer. You could also install them directly.

Further software support depends on the OS used. For example, Raspbian comes pre-installed with Python, Scratch, Sonic Pi, Java, and more. Python libraries Rpi.GPIO and Wiring Pi are useful for IoT programming.

### What resources can help a beginner learn Raspberry Pi?

The official website is a good place to start. The FAQ page will clarify many basic questions.

Get involved in the Pi community. Read the blog. Subscribe to the newsletter. *Raspberry Jams* are local meetups for sharing knowledge or collaborating on Pi projects. Use the Pi Forums to ask or give help. Get inspired by Pi projects that others have created.

Search online for tutorials, books, and projects posted on community websites. Programming the Raspberry Pi by Simon Monk is recommended for beginners. For inspiration, visit Instructables and Hackaday.

On Pi Day 2018, one blogger shared 314 useful resources for Raspberry Pi enthusiasts.

## Milestones

1980

In the 1980s, BBC Micro in the UK and Commodore 64 in the US make computers accessible to home users. BASIC programming language could be used to program these computers.

2006

Eben Upton at the University of Cambridge notices how fewer students are applying for computer science courses. He blames it on the lack of affordable computers for educational purpose. Children have access to only games consoles (and tablets and smartphones in later years). They have become consumers of content rather than programmers. Upton builds a computer using off-the-shelf parts and a soldering iron. It runs on an Atmel microcontroller.

Oct
2008

At a meeting involving Eben Upton (now an SoC architect at Broadcom), Alan Mycroft and Pete Lomas, the vision for Raspberry Pi takes shape. It's not about giving kids a black box. It should be a bare board that helps them know its components, tinker into open source code and learn how computers work. The second prototype is built using Broadcom components. The name **Raspberry Pi** is also coined, "Pi" because it boots into Python. A logo is selected later in 2011 via an open competition.

May
2009

To develop the Raspberry Pi and promote basic computer science in schools, **Raspberry Pi Foundation** is formed as a charity. Despite having the Foundation, the next two years would prove difficult for realizing the hardware at its desired price point of $35.

May
2011

A thumb-drive prototype of the Raspberry Pi is released in the UK. A YouTube video of the same picks up 600,000 views in just two days. This is made possible by a low-cost **ARM-based Broadcom SoC BCM2835** released in early 2011. The SoC was meant for applications such as electronic devices and digital signs, but now reimagined to power Raspberry Pi.

Aug
2011

The first 50 Raspberry Pi Alpha boards are released, built by Broadcom. The board has many features and interfaces that would become standard in later versions. However, it's $110 a piece plus slightly larger than the desired size of a credit card. Many design decisions are made to achieve the final $35 credit-card-sized Pi. The beta boards come out in December.

Feb
2012

The first Raspberry Pi **Model B** is released. Orders quickly reach 100,000. A simpler and cheaper variant of this called **Model A** is released in 2013. This has only 1 USB port and no Ethernet port.

2014

Raspberry Pi **Model B+** and **Model A+** are released. GPIO header increases from 26 to 40 pins. The new boards also use less power. Upton later comments that Model B+ is the one they intended to make back in 2012. The success of earlier models and high volumes driving down costs (2.5 million by February 2014), have helped achieve Model B+ at a retail price of $35.

Feb
2015

**Raspberry Pi 2 Model B** is released. Compared to Model B+, it doubles the RAM size from 512MB to 1GB. Speed increases from 700MHz to 900MHz. There are four USB ports rather than two, thus removing the need to get a USB hub. The SoC is based on quad-core ARM Cortex-A7.

Nov
2015

For applications that require fewer interfaces, there's already Model A and Model A+. By removing the pinout header, removing more interfaces, and reducing HDMI and USB to smaller form factors, **Raspberry Pi Zero** is released. It retails at only $5. It draws less than 1 Watt of power. In 2017, **Zero W** includes wireless connectivity. In 2018, **Zero WH** includes the GPIO pinout header.

Feb
2016

**Raspberry Pi 3 Model B** is released. It uses a 64-bit SoC. This becomes the first model to add wireless connectivity: Wi-Fi 802.11n and Bluetooth 4.1. This can also boot from a USB. In 2018, variants **Pi 3 Model B+** and **Pi 3 Model A+** are introduced with 802.11ac and Bluetooth 4.2.

2019

By end of February, 25 million units of Raspberry Pi are sold worldwide. In June, **Raspberry Pi 4 Model B** is released with support for 4K video.

Raspberry Pi


# Software Performance Testing

## Summary

Performance testing helps identify bottlenecks in a system, establish a baseline for future testing, support a performance tuning effort, and determine compliance with performance goals and requirements.

Performance testing is an ongoing task throughout the life cycle of the project. It not only involves testers, but also developers and operations to run and maintain the application to its performance expectations.

Performance, load, and stress tests are subcategories of performance testing, each intended for a different purpose.

## Discussion

### What is performance testing in software?

Performance testing is a type of non-functional testing. It's intended to determine the responsiveness, throughput, reliability, and/or scalability of a system under a given workload.

Performance testing is testing that is performed to determine how fast some aspect of a system performs under a particular workload. It can serve different purposes, such as to demonstrate that the system meets performance criteria.

In the past, performance testing was a specialized activity managed by separate teams, not the developers. The process typically took weeks and even months. With the transition to Agile and DevOps, this has changed. Using open source and commercial tools, it's now become possible to do performance testing by developers in shorter time scales.

### What should be the focus of performance testing?

Following are some focus areas for performance testing:

    + **Speed**: Determines whether the software application responds quickly.
    + **Scalability**: Determines maximum user load the software application can handle.
    + **Stability**: Determines if the application is stable under varying loads.

### What are the common goals of performance testing?

Performance testing has the following goals:

    + Assess production readiness
    + Evaluate against performance criteria
    + Compare performance characteristics of multiple systems or system configurations
    + Find the source of performance problems
    + Support system tuning
    + Find throughput levels

### What are the types of performance testing?

Each type of performance testing has a specific focus as noted below:

    + **Load Testing**: Checks the application's ability to perform under anticipated user loads. The objective is to identify performance bottlenecks before the software application goes live.
    + **Stress Testing**: Also called *Breakpoint Testing*, this involves testing an application under extreme workloads to see how it handles high traffic or data processing. The objective is to identify breaking point of an application.
    + **Endurance Testing**: Also called *Soak Testing*, this is done to make sure the software can handle the expected load over a long period of time.
    + **Spike Testing**: Tests the software's reaction to sudden large spikes in the load generated by users.
    + **Volume Testing**: Large amount of data is populated in database and the overall software system's behavior is monitored. The objective is to check software application's performance under varying database volumes.
    + **Scalability Testing**: Determine the software application's effectiveness in "scaling up" to support an increase in user load. It helps plan capacity addition to your software system.

### What are the steps of performance testing?

We may list the following steps:

    + **Identify the Test Environment**: Identify the physical test environment and the production environment, which includes the hardware, software, and network configurations.
    + **Identify Performance Acceptance Criteria**: Identify the response time, throughput, and resource utilization goals and constraints. In general, response time is a user concern, throughput is a business concern, and resource utilization is a system concern.
    + **Plan and Design Tests**: Identify key scenarios, determine variability among representative users such as unique login credentials and search terms.
    + **Configure the Test Environment**: Prepare the test environment, tools, and resources necessary to execute each strategy as features and components become available for test.
    + **Implement the Test Design**: Develop the performance tests in accordance with the test design best practice.
    + **Execute the Test**: Run and monitor your tests. Validate the tests, test data, and results collection.
    + **Analyze Results, Report, and Retest**: Consolidate and share results data. Analyze the data both individually and as a cross-functional team. Re-prioritize the remaining tests and re-execute them as needed.

### What performance parameters are monitored during performance testing?

The following are commonly monitored:

    + **Processor Usage**: Amount of time processor spends executing non-idle threads.
    + **Memory Use**: Amount of physical memory available to processes on a computer.
    + **Disk Time**: Amount of time disk is busy executing a read or write request.
    + **Bandwidth**: Shows the bits per second used by a network interface.
    + **Private Bytes**: Number of bytes a process has allocated that can't be shared amongst other processes.
    + **Memory Pages per Second**: Number of pages written to or read from the disk in order to resolve hard page faults.
    + **Page Faults per Second**: Overall rate in which fault pages are processed by the processor.
    + **Response Time**: Time from when a user enters a request until the first character of the response is received.
    + **Throughput**: Rate a computer or network receives requests per second.
    + **Maximum Active Sessions**: Maximum number of sessions that can be active at once.
    + **Hits per Second**: Number of hits on a web server during each second of a load test.
    + **Database Locks**: Locking of tables and databases.
    + **Thread Counts**: Number of threads that are running and currently active.

### Could you give pointers on performance testing in the cloud?

**Cloud-based performance testing** refers to the use of cloud technologies to test your application or service. Your application itself may not be on the cloud but the load generation, report collection and test monitoring is done in the cloud. The obvious benefit is lowering infrastructure cost, testing at scale, simulating load coming from different geographic regions, and more.

This should not be confused with **cloud performance testing**, where the idea is to validate the performance of an application deployed in the cloud. The general approach to performance testing, types of tests and parameters monitored remain the same but with some aspects particular to cloud. For example, storage, processing, bandwidth and number of users become important. In particular, parameters related to management of virtual machines, containers, microservices, database connections, all need to be validated.

Tests should validate how well and fast can the cloud infrastructure adapt to varying load. Elasticity, scalability, availability, fault tolerance and reliability are all important measures. This includes the performance of logging, raising alarms, or sending notifications, across all the cloud services used by the application.

### Could you name a few performance testing tools?

Some open source tools include Apache JMeter, K6, LoadUI, and Grinder. Commercial tools requiring a license include HP LoadRunner, IBM Rational Performance Tester, and Microfocus SilkPerformer.

When selecting a particular tool, you must evaluate the supported features. One blogger has shared a feature comparison of some tools with respect to scripting, execution and reporting.

Wikipedia gives a useful list of load testing tools.

## Milestones

1989

Mercury Interactive is founded in California. It releases **LoadRunner**, one of the first performance testing tools.

Dec
1998

**JMeter** is released as an open source functional plus performance testing tool. In November 2011, it becomes a top-level Apache project.

2001

**OpenSTA** is released as an open source web load and performance testing tool.

2004

Software Test & Performance magazine is launched by BZ Media. It's later renamed to Software Test & Quality Assurance magazine. A curated list of magazines and blogs for software testing is also available.

2011

Based on JMeter, commercial tool **BlazeMeter** is released. Fourth generation of BlazeMeter is released in 2018 and it enables Continuous Testing. BlazeMeter enhances JMeter with scalability, reporting, collaboration, and test management features.

Software Performance Testing


# Concurrency vs Parallelism

## Summary

Concurrency and Parallelism are both prominent processing techniques used by the OS when multiple computer processes are pending to be executed by it.

Concurrency implies multiple tasks can be executed in an overlapping time period. So one task may be started before the previous one finishes, but they will not be running at the same instant of time. Instead, the processor will allot time slices per task and switch contexts suitably (multitasking on a single-core machine). Concurrency is hard to implement and debug.

Parallelism describes the ability for independent tasks of a program to be physically executed at the same instant of time. These tasks may run simultaneously: on another processor core, another processor or an entirely separate computer (distributed systems). With ever-increasing demand for computing speed from real-world applications, parallelism is becoming ubiquitous and increasingly affordable.

## Discussion

### Can you introduce the common terms used in concurrency and parallelism?

Here are some essential terms to know:

    + **Multiprocessing**: Two or more CPUs within a single computer system sharing Memory and IO resources.
    + **Distributed Computing**: Computing system with multiple components (Memory, CPU, IO) located on different machines. Resources are shared. Information is exchanged internally to appear as a single coherent system to the end user.
    + **Multicore processor**: Combines two or more independent CPUs into one package (Single IC). Examples: Intel Core 2 duo, Qualcomm Snapdragon Octacore processor chips.
    + **Multi-threading**: When a process runs multiple sub-tasks (threads) to perform various operations at the same time. Individual threads are controlled by a main thread of execution. Data is exchanged using shared memory.
    + **Pipelining**: Sequential execution of related tasks where output of one task becomes input for the next task in the pipeline. This ordering helps maximise processor utilization.
    + **Clock cycle**: Speed at which a CPU performs a basic operation. Example: 4 GHz processor has a cycle time of 0.25ns.
    + **Time Sharing**: Allocation of computer resources in time slots to several programs. Uses CPU scheduling and multi-programming to provide each user with a processor time slice.

### How does concurrent processing work?

Goal of concurrency is to minimise CPU idle time. Another process/thread gets CPU allocation while present process/thread is waiting for input/output operation, database transaction or invoking an external application. An interrupt is sent to the active task to pause it. Task-related data stored in RAM is context switched to the new task.

If two or more tasks are running on a single-core CPU (or on the same core in a multicore processor), they can concurrently access the same resources. Data read operations are safe when done in parallel. Programmers need to manage data integrity during write access.

Efficient scheduling of tasks is vital in a concurrent system. Popular task scheduling algorithms include FIFO, Shortest Remaining Time, Strict Priority, and Round-Robin.

In order to prevent task starvation when one task hogs the CPU for too long, interrupts are designed to pause it and give CPU allocation to other tasks. This is called **preemptive scheduling**. To manage scheduling/dispatching of concurrent tasks, the OS itself needs CPU time like any application program.

Executing tasks in batches may also minimise idle time. Costly operations such as IO/Memory fetch are done just once per batch.

### How is parallelism implemented in various computer systems?

A computer's performance depends directly on the time required to perform a basic operation and the number of basic operations that can be performed in parallel. Clock cycle of a processor is the minimum time taken to perform a basic operation, which is already near the speed of light in modern computers. Parallelism is therefore necessary for performance gains:

    + Increase internal concurrency in operations at chip level (very expensive VLSI design)
    + Process pipelining
    + Multiple function units (several multipliers, adders managed by one instruction set)
    + Multiple cores (CPUs) in the same computer sharing memory and IO. This makes parallelism possible even in smaller devices like mobile phones, tablets or smart car systems.
    + Distributed systems of multiple independent computers with their own memory and IO. This has become a prevalent and feasible option with greatly improved networking speeds (100 Tbps achieved during research in year 2020).With real-world applications becoming more data intensive and new devices getting added to the digital network every day, parallel computing is the way forward. Computer architectures used to sustain this growth are changing radically, from sequential to parallel.

### Can you explain concurrency and parallelism with an example?

A simple example for concurrent processing would be any user interactive application such as a document editor. Every time a function involves user action, the processor cycles are wasted. Instead, control is ceded to some background operation the application may require. When file is being saved or printed (in the background), user can concurrently type.

The main thread of the word processor spawns several threads when needed – for character typing, saving to disk, despatching to printer, etc. They may execute within a common time frame but they are not really executing in parallel.

In contrast, a Hadoop-based distributed data processing system is a good example of a parallel processing. It consists of large-scale data processing on clusters using massively parallel processors.

The parallelization and command control distribution is automatic. A clean abstraction is presented to programmers who can see the whole system as one database. Typical specifications include 40 nodes/rack, 1000-4000 nodes in cluster, 1 Gbps bandwidth in rack, 8 Gbps out of rack. Node specifications include 8-16 cores, 32 GB RAM, 8×1.5 TB disks.

### How is information shared between processes in both these techniques?

Every OS process consists of allocated memory for program code, data, and a heap for dynamic memory allocations. Threads spawned within the process have their own call stacks, virtual CPU and local storage. But they share the application's heap, data, codebase and resources (such as file handles) with other threads in the same process.

Threads share data and code while processes don't. The stack is not shared for both.

Static data is shared between threads from common shared memory. Other data is shared through arguments/parameters and references, as long as the data is allocated. All allocated storage, unless freed explicitly, is not freed until program termination. Data serialization is the user's responsibility.

All files are shared between threads. If a thread (other than main) opens a file, it must be closed before that thread terminates.

CPU parallelism in multi-core systems is different from distributed systems because of shared memory availability. In distributed systems, Message Passing Interface (MPI) allows communication of information between various nodes and clusters. It's commonly used in High Performance Computing (HPC) systems. It may be used in multi-core systems as well, thus presenting a unified abstraction.

### How are the concurrent and parallel processes scheduled for execution?

Basic sequence of concurrent process execution is more or less similar for OS tasks and application program tasks. Initially, a bootstrap program (such as init or main thread) starts execution. Then a software or hardware interrupt is raised to request a new thread of execution. Once interrupted, CPU stops what it's doing and immediately transfers execution to the starting address of the interrupting service routine. Return addresses of interrupted threads are stored in a system stack for resuming execution later.

The Task Scheduler schedules and coordinates concurrent tasks at runtime. Combination of pre-emptive and cooperative scheduling algorithms are used for task sequencing. Goal is to achieve maximum usage of processing resources. Higher priority tasks are allowed to 'steal' CPU resources from other threads. Sometimes threads simply timeout and cede their CPU control. Threads may also keep polling to check for free CPU availability.

In modern parallel processing systems, the NIC supports multiple queues, so thread states don't need to be transferred between cores/CPUs. One thread per core will receive, multiple threads per core will process. Event-based programming and asynchronous IO access are used.

### What are the prevalent parallel processing techniques in today's data intensive real-world systems?

The key to implementing parallel computing systems is designing sub-tasks and operations independent of each other. Except for start and end of each task, there should be no data dependency. Tasks involving a lot of data transfer/communication between them are difficult to parallelize.

Parallel computing may be done using three different kinds of hardware platforms - multicore systems, clusters and graphics processing units (GPUs). Parallelisation at the software deployment level happens using containerised applications and virtualization techniques.

For instance, Kubernetes supports allocating different amounts of memory and CPU for each container. So complex multi-threaded algorithms (like XGBoost) can get more resources compared to single-threaded algorithms (such as LogisticRegression from sklearn). We can make the most of our resources, minimise cost and run more pipelines simultaneously.

A popular parallel programming model for processing big datasets is MapReduce. Blocks of data are processed in parallel via these steps: Read data in blocks → Map them as key-value pairs → Reduce the data by performing summary operations → Write the reduced data into storage systems.

### What languages provide for concurrency and parallelism?

Concurrent programming languages use the concept of simultaneously executing processes or threads as a means of structuring a program. A parallel language allows programming constructs executable on more than one processor. Concurrency programming techniques may be used in parallel programs too but not a must. The taxonomy of parallelism involves instruction stream and data stream.

The three main components in these languages are:

    + Performance computing (concurrent execution for CPU resource optimization)
    + Distributed computing (parallel CPUs to be controlled and utilized)
    + Systems programming (basic OS/hardware management)The different languages can be categorised as follows:

    + Object-Oriented Parallelism: Presto, Orca, Nexus, Java, High Performance C++
    + Shared Memory Languages: Linda, Orca, SDL, PThreads, Java
    + Distributed Memory Paradigms: Parallel Virtual Machine (PVM), MPI, Concurrent C, Ada, Fortran M, C\*
    + Message Passing: Rust, SmallTalk, Go
    + Parallel Logic Systems: Concurrent Prolog, GHC, Strand
    + Parallel Functional Languages: LISP, MultiLISP, SISAL
    + Frameworks and APIs: Apache Hadoop, Spark, Beam, OpenCLIn some cases, concurrency or parallelism features may be provided as a library extension and not part of the main language (Eg. POSIX thread library).

## Milestones

1960

An academic study of concurrent algorithms starts as early as the 1960s, with Dijkstra (1965) credited with publishing the first paper in this field, identifying and solving mutual exclusion.

1985

A new kind of parallel computing is launched by the Caltech Concurrent Computation project by building a supercomputer for
 scientific applications from 64 Intel 8086/8087 processors. These massively parallel processors (MPPs) dominate the top end of computing.

1995

Mathematical models to analyse concurrent systems performance and complexity in the form of Petri nets are published in a critical research paper by Esparza and Nielsen.

1999

NVIDIA invents the **Graphics Processing Unit (GPU)** as a symmetric multicore parallel processor separate from the CPU.

2001

IBM introduces the first multicore processor VLSI chip with two 64-bit microprocessors comprising of more than 170 million transistors.

2002

Intel adds support for simultaneous multithreading to the Pentium 4 processor, under the name **hyper-threading**. Until then most desktop computers had only one single-core CPU, with no support for hardware threads.

2004

Parallel data processing in large clusters becomes possible using the **MapReduce** parallel programming model.

2014

Container management platforms such as **Kubernetes** enter the market specialising in handling clusters for scalable cloud-based solutions.

Sep
2014

At a Stanford seminar, Joe Armstrong, the creator of Erlang programming language, notes that engineering **fault tolerant and scalable systems** require understanding of distributed, parallel, concurrent computing.

Concurrency vs Parallelism


# Container Security

## Summary

With the wide adoption of container-based applications, systems became more complex and security risks increased. This laid the groundwork for container security. Vulnerabilities like dirty copy-on-write only furthered this thinking. This led to a shift left in security along the software development lifecycle, making it a key part of each stage in container app development, also known as **DevSecOps**. The goal is to build secure containers from the ground up without reducing time to market.

DevOps practice has enabled faster release cycles. At runtime, an application may dynamically scale to hundreds or even thousands of containers. It's impossible to have manual policies to secure these containers. Moreover, a production environment involves many layers such as images, registries, orchestrators and container runtimes. Hence, traditional security practices can't be directly applied to securing containers.

## Discussion

### Which are the basic security mechanisms that come with containers?

In terms of filesystem, networking and processes, containers are isolated from one another using **namespaces**. To control access to resources such as CPU and RAM, there's **cgroups**.

To control kernel calls from a container, we use Linux kernel features called **capabilities** and **seccomp**. Capabilities provides fine-grained access control such as denying "mount" operations or access to raw sockets. Even if someone gains root access within a container, the damage they can do is limited. Secure computing mode (seccomp) disables access to system calls except those allowed. Both these adopt a whitelist approach.

Red Hat distributions comes with SELinux while Debian distributions come with AppArmor. Both these are security modules that provide access control by implementing **Mandatory Access Control (MAC)**. Only users and processes with sufficient permissions can perform various actions. The access policies can't be changed by users.

We can also run the kernel with GRSEC and PAX to provide extra compile-time and runtime safety checks.

### Is it okay to run my process with root access within the container?

Some processes running on typical servers run with root privileges. Examples are SSH daemon, cron daemon, logging daemons, kernel modules, and network configuration tools. It may therefore appear that these processes need to run with root privileges inside a container. In reality, such tasks are handled by the infrastructure surrounding the container such as the host machine or the container platform. Even when a specific process needs root privilege, limit access using *capabilities*.

In general, stick to the **principle of least privilege**. Don't give more permissions than needed. One way to implement this is to use known user ID and group ID that have the minimum required privileges. An alternative available in Docker is to use a command-line option; example, `docker run --user 1001 ...`, which avoids root access.

Most processes inside containers are app services and should not require root access. Docker itself requires root access but not the containers.

### What are the various security threats facing containers?

NIST has identified key threats to containers:

    + **Image**: An image may lack security updates or become outdated, particularly when security bugs have been discovered after the image was created. Image may contain a misconfiguration, such as running a command with a greater privilege than needed. Image may include malware, particularly when a base layer comes from a third party or untrusted source. Secrets such as SSH private keys may be in the image as clear texts.
    + **Registry**: Images stored at registries may be stale. Registries themselves can be compromised. Pulling images over insecure connections is also an issue.
    + **Orchestrator**: If access privileges are not properly scoped, users can access and affect containers that don't belong to them. Wrong configurations may allow unauthorized nodes to join a cluster.
    + **Container**: At runtime, a malicious software can affect other containers or the host OS. App vulnerabilities can affect the container. Unplanned or unsanctioned containers, especially in a development environment, are a risk.
    + **Host**: The host itself has an attack surface. Because the kernel is shared, runtime isolation is not as high as that of hypervisors.

### What are some best practices to secure containers?

We list some industry best practices to secure containers:

    + Called image provenance, have a system such as *Docker Content Trust* to identify the source of an image that's running in production.
    + Containers must run with minimum resources and privileges. Use *AppArmor* or *SELinux* to enforce access control. Perhaps the most important advice is to not use root privilege to run the container's main process.
    + At runtime, detect threats and respond to the same automatically.
    + Vulnerability scanning, regular auditing, and software updates must be automated.
    + Since containers are not permanent, traditional operational models may not work. Organizations may have to formalize new models.
    + Use *Docker Bench for Security* to know if you're following best practices around container deployment.
    + Minimize the use of third-party images and use only signed images.
    + Mount the host filesystem as read-only or disable UNIX sockets, thus limiting access to an attacker.

### Isn't it better to use VMs instead of containers for better security?

Containers offer only software-based isolation using namespaces and cgroups. Multiple containers share the same kernel. If one container is compromised, the attacker can potentially gain access to other containers on the host. This is where the hypervisor layer of VMs provides hardware-enforced isolation.

But it's possible to mix both VMs and containers. By running multiple containers inside a VM, we get the performance of containers without sacrificing the security of hypervisor. It's common among cloud providers to isolate tenants using VMs. For greater security, we can use VMs to separate containers that need to run at different security levels. For example, a billing service may run at a higher security level compared to a user-facing web service.

Joyent and IBM isolate tenants by running containers on bare metal without using VMs. Hyper, Intel and VMware are building fast VM-based frameworks with the aim of getting the best of both worlds. The idea is to secure a container without the bloat of a VM. This is being called **Kata Containers**. It uses *runV* container runtime.

### Which tools can help me secure my containers?

While container platforms and containers themselves offer a basic level of security, this isn't enough. There's a need to scan container images or monitor a running container. There are many vendors offering products that do these. Some of them are Alert Logic, Anchore, Aporeto, Aqua Security, Capsule8, NeuVector, Qualys, StackRox, Sysdig, and Twistlock.

Any good tool should have visibility of containers, images and host processes. It should validate container signatures. It should alert when there are image drifts. It should monitor slaves and masters of Swarm or Kubernetes clusters. Tool should have an easy-to-use dashboard. It should make use of image metadata to enable filtering by labels and tags. It should classify threats by severity and priority. Select a tool that integrates well with your CI/CD pipeline.

Google's Container Registry vulnerability scanning, Red Hat's Atomic Scan, IBM's Bluemix Vulnerability Advisor, CoreOS Clair, Docker Security Scanning, Aqua Security's Peekr, and Twistlock Trust can do security scanning. Runtime threat detection and response are offered by Aqua Security, Joyent Triton SmartOS, Twistlock and Red Hat OpenShift.

## Milestones

Aug
2015

**Docker Content Trust (DCT)** is released as a new feature in Docker Engine 1.8. This adds a digital signature to an image before it's pushed to the registry. When images are pulled, the signatures are verified. Through the implementation of The Update Framework (TUF), rollback attacks and freeze attacks are also prevented.

Oct
2016

By using a vulnerability in the Linux kernel, called Dirty Copy-on-Write or CVE-2016-5195, one researcher creates an exploit that achieves **container escape**, essentially allowing the attacker to do things outside the container. The exploit uses Linux's virtual Dynamic Shared Object (vDSO).

Sep
2018

Google launches beta version of **Container Registry vulnerability scanning**. This helps within a CI/CD pipeline and prevents deployment of images that have vulnerabilities.

Jan
2019

Two researchers discover a way to escape from a container into the host system and obtain root privileges. This is possible with a compromised container even if it's using the default or hardened configuration. The exploit overwrites `docker-runc` binary on the host with malicious software. This bug in runc, called CVE-2019-5736, affects Docker and other container platforms. A patch is released in February.

Container Security


# Wi-Fi Security

## Summary

Wi-Fi security has been a concern due to the wireless nature of access. With wired networks such as Ethernet, a hacker needed physical access to the equipment. With Wi-Fi, attacks can be launched in a vicinity where the signal can be picked up. It's therefore important to not only control who is allowed to get into a Wi-Fi network but also protect all data that's being exchanged over the network. With the coming of IoT, Wi-Fi security is likely to be more important than ever before.

Attacks on Wi-Fi can be passive such as sniffing the radio channels to pick up useful information. It can be more active such as a rogue device impersonating as an authentic access point or client. Wi-Fi security needs to address all these aspects.

## Discussion

### What does security mean in the context of Wi-Fi?

Wi-Fi security can be seen in two aspects:

    + Authentication: This controls who is allowed to log into the network. Wi-Fi clients have to provide the right credentials to connect to an access point (AP). This is usually a password but more sophisticated methods are possible using Extensible Authentication Protocol (EAP) and IEEE 802.1x. A Wi-Fi password is also called passphrase or Network Security Key. From the perspective of authentication, a client is also called supplicant.
    + Encryption: Data is encrypted so that others cannot read it.Authentication and encryption are sometimes called "security" and "privacy" respectively. These are implemented at the MAC layer, meaning that protection is only between the client and the access point. What's also important is end-to-end security. Keeping your data and network secure usually involves more than just Wi-Fi. Security protocols can be employed at different layers. IPsec protects data at the IP layer. TLS and SSL protect data at the transport/session/application layers. SSH protects data at the application layer. For browsing webpages in a secure manner, HTTPS relies on SSL/TLS. In addition, firewalls, VPNs and anti-virus software can be used.

### What steps can I take to secure my Wi-Fi network?

The following are best practices for a secure Wi-Fi network:

    + A Wi-Fi router or access point will come with default SSID and password. Change these to non-default values. Use a strong password.
    + Periodically change the network password.
    + Enable encryption. The use of WPA2-AES is recommended. Use a Wi-Fi CERTIFIED product since it's certified for WPA2 support.
    + Since WPS is a security risk, disable this feature completely.
    + Router manufacturers often release updates including security enhancements or patches. Update your router with the latest firmware releases.
    + Allow administrative web access to your router via HTTPS and block HTTP access. Disable wireless admin access. In addition, disable remote management, so that settings can be changed only by someone with physical access to the router. Change admin credentials to non-default values. Use a strong admin password.
    + Restrict the signal to within your house by using anti-Wi-Fi paint.

### What are some myths about Wi-Fi security?

Here are some things you can do but these are not going to make your network more secure since tools exist to overcome them:

    + Disable broadcast of SSID to prevent casual folks from trying to connect to your access point.
    + Configure access point to allow connections from a whitelist of known clients. This is usually specified with client MAC address.
    + Disable DHCP and allocate IP addresses to a limited range.
    + Reduce the range of the Wi-Fi signal but a hacker will probably use a higher gain antenna.

### What precautions can I take to secure my Wi-Fi client and its data?

The following are recommended:

    + Don't allow automatic connections to open Wi-Fi access points. These access points may be potentially dangerous. In other words, enable WPA2 security. Or configure client to prompt the user for approval before connecting.
    + Disable clients from sending out probes looking for an available access point.
    + If a client has highly sensitive data, you can allow it to connect only to a whitelist of access points.
    + Disable sharing of your connection to other devices nearby, particularly when using a public AP.
    + Use a VPN so that data is always encrypted before it leaves your device. This way, a rogue AP will be rendered useless even if Wi-Fi connection has been compromised.

### Which security protocol should I choose?

You should use the latest standards, WPA3-Personal or WPA3-Enterprise. On older devices, use Wi-Fi Protected Access II (WPA2) together with Advanced Encryption Standard (AES). For home or personal use, use WPA2-PSK, where PSK implies pre-shared key (usually called password). WPA2-Enterprise is used when the network supports additional methods of authentication. Wi-Fi Alliance has branded IEEE 802.11i as WPA2. WPA may be seen as a partial implementation of IEEE 802.11i.

Historically, Wi-Fi security protocols include WEP (Wired Equivalent Privacy), WPA, WPA2 and WPS (Wi-Fi Protected Setup). WEP and WPS are no longer secure. WPA was designed to replace WEP on old device hardware.

Encryption methods and integrity checks are also important. WEP uses RC4 stream cipher for encryption and CRC32 for integrity check. WPA uses RC4 (or AES if supported by device) but enhances it with Temporal Key Integrity Protocol (TKIP); and it uses a 64-bit Message Integrity Check (MIC) named MICHAEL. WPA2 uses AES, which is secure. More accurately, an AES-standard named CCMP is used.

The use of WPA and TKIP can limit the performance of your router. There are known attacks against TKIP.

### Are there any known vulnerabilities with WPA2?

In October 2017, "key reinstallation attacks (KRACKs)" were used successfully to read sensitive information previously assumed to be encrypted. This was not merely an implementation bug but a flaw in the WPA protocol itself. When a client wants to join a Wi-Fi network, it does a handshake that includes initialization of cryptographic keys. In this attack, the client can be tricked to reuse existing keys as well as reset counters to their initial values.

KRACK may include arbitrary packet decryption and injection, TCP connection hijacking, HTTP content injection, or the replay of unicast and group-addressed frames. Vendors are known to provide updated firmware that fixes the KRACK vulnerability.

WPA3 replaces WPA2 as the latest Wi-Fi security standard. Cisco has stated that they will offer WPA3 on older devices via a firmware upgrade.

### What is WPS and should I use it?

Wi-Fi Protected Setup (WPS) was introduced into the Wi-Fi standard to simplify the setup process. Rather than enter long passwords, an 8-digit pin is used to connect a client to the access point. WPS has a few different ways that require either physical or admin access to the devices. The 8-digit pin is usually mentioned on the device hardware, be it client or router or both.

The use of WPS is not recommended. Vulnerabilities in WPS were discovered in 2011 and a brute force attack is enough. A simple explanation of how this attack works is given by Paul Ducklin. In one case, the attack succeeded in just six hours.

### Can you name some well-known attacks on or using Wi-Fi networks?

In 2003, an open Wi-Fi network of Lowe's became the entry point for two hackers. They accessed servers across seven US states and crashed a PoS system. In 2004, BJ's was hacked and credit card numbers were stolen. This was due to unencrypted networks and use of default credentials. BJ's incurred legal costs of about $10 million. In 2005, GE Money in Finland lost 200,000 Euros due to an unprotected Wi-Fi. In 2007, hackers exploited WEP's weaknesses and stole credit card numbers from Marshalls department store in St. Paul, Minnesota.

### What tools or products exist to snoop a Wi-Fi network or audit its security?

For scanning the airwaves for 802.11x traffic we have Wireshark, inSSIDer, Kismet, Pwnie Express Pwn Pro, and Netstumbler. Airsnarf is one tool to impersonate an access point. Airpwn can be used to inject packets at the access point and fool the client. Airsnort and Aircrack are for attacking WEP. To simply jam the radio spectrum, Wave Bubble is one device. Aircrack and coWPAtty can be used to attack WPA. To spoof a MAC address, Nmap and MAC Shift are handy. To know if there's an unauthorized access in your network, AirSnare is useful. Default passwords for well-known products are listed publicly.

## Milestones

1999

WEP is standardized as the security protocol for Wi-Fi.

2001

Berkeley researchers discover vulnerabilities in WEP.

2003

WPA is ratified by Wi-Fi Alliance as a replacement to the vulnerable WEP.

2004

Due to WPA's weak integrity check using MICHAEL, WPA2 comes out. It's a complete implementation of IEEE 802.11i standard.

Mar
2006

Wi-Fi Alliance requires that all devices must be WPA2 certified in order to use the Wi-Fi trademark.

Jan
2007

WPS is officially launched by Wi-Fi Alliance.

Dec
2011

WPS is found to be vulnerable to brute force attacks. There are design flaws in WPS and also implementation flaws in many popular Wi-Fi routers.

Jun
2018

Wi-Fi Alliance releases WPA3 that aims to "simplify Wi-Fi security, enable more robust authentication, and deliver increased cryptographic strength for highly sensitive data markets". This is a welcome news given that WPA2 was compromised in October 2017.

Apr
2019

Researchers discover vulnerabilities in WPA3's Dragonfly key exchange. These vulnerabilities are collectively termed **Dragonblood**. Wi-Fi Alliance announces an update to the WPA3 to fix these vulnerabilities. Vendors can push this to existing devices via a software update.

Wi-Fi Security