Home Blog Page 347

How I use Wireshark

Hello! I was using Wireshark to debug a networking problem today, and I realized I’ve never written a blog post about Wireshark! Wireshark is one of my very favourite networking tools, so let’s fix that 🙂

Wireshark is a really powerful and complicated tool, but in practice I only know how to do a very small number of things with it, and those things are really useful! So in this blog post, I’ll explain the 5 main things I use Wireshark for, and hopefully you’ll have a slightly clearer idea of why it’s useful.

what’s Wireshark?

Wireshark is a graphical network packet analysis tool.

On Mac, you can download & install it from their homepage, and on Debian-based distros you can install it with sudo apt install wireshark. There’s also an official wireshark-dev PPA you can use to get more up-to-date Wireshark versions.

Wireshark looks like this, and it can be a little overwhelming at first. There’s a slightly mysterious search box, and a lot of packets, and how do you even use this thing?

Read more at Julia Evans

AGL Outlines Virtualization Scheme for the Software Defined Vehicle

Last August when The Linux Foundation’s Automotive Grade Linux (AGL) project released version 4.0 of its Linux-based Unified Code Base (UCB) reference distribution for automotive in-vehicle infotainment, it also launched a Virtualization Expert Group (EG-VIRT). The workgroup has now released a white paper outlining a “virtualized software defined vehicle architecture” for AGL’s UCB codebase.

The paper explains how virtualization is the key to expanding AGL from IVI into instrument clusters, HUDs, and telematics. Virtualization technology can protect these more safety-critical functions from less secure infotainment applications, as well as reduce costs by replacing electronic hardware components with virtual instances. Virtualization can also enable runtime configurability for sophisticated autonomous and semi-autonomous ADAS applications, as well as ease software updates and streamline compliance with safety critical standards.

The paper also follows several recent AGL announcements including the addition of seven new members: Abalta Technologies, Airbiquity, Bose, EPAM Systems, HERE, Integrated Computer Solutions, and its first Chinese car manufacturer — Sitech Electric Automotive. These new members bring the AGL membership to more than 120. 

AGL also revealed that Mercedes-Benz Vans is using its open source platform as a foundation for a new onboard OS for commercial vehicles. AGL will play a key role in the Daimler business unit’s “adVANce” initiative for providing “holistic transport solutions.” These include technologies for integrating connectivity, IoT, innovative hardware, on-demand mobility and rental concepts, and fleet management solutions for both goods and passengers.

The Mercedes-Benz deal follows last year’s announcement that AGL would appear in 2018 Toyota Camry cars. AGL has since expanded to other Toyota cars including the 2018 Prius PHV.

An open-ended approach to virtualization

Originally, the AGL suggested that EG-VIRT would identify a single hypervisor for an upcoming AGL virtualization platform that would help consolidate infotainment, cluster, HUD, and rear-seat entertainment applications over a single multicore SoC. A single hypervisor (such as the new ACRN) may yet emerge as the preferred technology, but the paper instead outlines an architecture that can support multiple, concurrent virtualization schemes. These include hypervisors, system partitioners, and to a lesser extent, containers.

Virtualization benefits for the software defined vehicle

Virtualization will enable what the AGL calls the “software defined vehicle” — a flexible, scalable “autonomous connected automobile whose functions can be customized at run-time.” In addition to boosting security, the proposed virtualization platform offers benefits such as cost reductions, run-time flexibility for the software-defined car, and support for mixed criticality systems:

  • Software defined autonomous car — AGL will use virtualization to enable runtime configurability and software updates that can be automated and performed remotely. The system will orchestrate multiple applications, including sophisticated autonomous driving software, based on different licenses, security levels, and operating systems.

  • Cost reductions — The number of electronic control units (ECUs) — and wiring complexity — can be reduced by replacing many ECUs with virtualized instances in a single multi-core powered ECU. In addition, deployment and maintenance can be automated and performed remotely. EG-VIRT cautions, however, that there’s a limit to how many virtual instances can be deployed and how many resources can be shared between VMs without risking software integration complexity.

  • Security — By separating execution environments such as the CPU, memory, or interfaces, the framework will enable multilevel security, including protection of telematics components connected to the CAN bus. With isolation technology, a security flaw in one application will not affect others. In addition, security can be enhanced with remote patch updates.

  • Mixed criticality — One reason why real-time operating systems (RTOSes) such as QNX have held onto the lead in automotive telematics is that it’s easier to ensure high criticality levels and comply with Automotive Safety Integrity Level (ASIL) certification under ISO 26262. Yet, Linux can ably host virtualization technologies to coordinate components with different levels of criticality and heterogeneous levels of safety, including RTOS driven components. Because many virtualization techniques have a very limited footprint, they can enable easier ASIL certification, including compliance for concurrent execution of systems with different certification levels.

IVI typically requires the most basic ASIL A certification at most. Instrument cluster and telematics usually need ASIL B, and more advanced functions such as ADAS and digital mirrors require ASIL C or D. At this stage, it would be difficult to develop open source software that is safety-certifiable at the higher levels, says EG-VIRT. Yet, AGL’s virtualization framework will enable proprietary virtualization solutions that can meet these requirements. In the long-term, the Open Source Automation Development Lab is working on potential solutions for Safety Critical Linux that might help AGL meet the requirements using only open source Linux.</ul>

Building an open source interconnect

The paper includes the first architecture diagrams for AGL’s emerging virtualization framework. The framework orchestrates different hypervisors, VMs, AGL Profiles, and automotive functions as interchangeable modules that can be plugged in at compilation time, and where possible, at runtime. The framework emphasizes open source technologies, but also supports interoperability with proprietary components.

AGL virtualization approach integrated in the AGL architecture.

The AGL application framework already supports application isolation based on namespaces, cgroups, and SMACK. The framework “relies on files/processes security attributes that are checked by the Linux kernel each time an action processes and that work well combined with secure boot techniques,” says EG-VIRT. However, when multiple applications with different security and safety requirements need to be executed, “the management of these security attributes becomes complex and there is a need of an additional level of isolation to properly isolate these applications from each other…This is where the AGL virtualization platform comes into the picture.”

To meet EG-VIRT’s requirements, compliant hardware virtualization solutions must enable CPU, cache, memory, and interrupts to create execution environments (EEs) such as Arm Virtualization Extensions, Intel VT-x, AMD SVM, and IOMMU. The hardware must also support a trusted computing module to isolate safety-security critical applications and assets. These include Arm TrustZone, Intel Trusted Execution Technology, and others. I/O virtualization ​support for GPU and connectivity sharing is optional.

The AGL virtualization platform does not need to invent new hypervisors and EEs, but it does need a way to interconnect them. EG-VIRT is now beginning to focus on the development of an open source communication bus architecture that comprises both critical and non-critical buses. The architecture will enable communications between different virtualization technologies such as hypervisors and different virtualized EEs such as VT-x while also enabling direct communication between different types of EEs.

Potential AGL-compliant hypervisors and partitioners

The AGL white paper describes several open source and proprietary candidates for hypervisor and system partitioners. It does not list any containers, which create abstraction starting from the layers above the Linux kernel.

Containers are not ideal for most connected car functions. They lack guaranteed hardware isolation or security enforcement, and although they can run applications, they cannot run a full OS. As a result, AGL will not consider containers for safety and real time workloads, but only within non-safety critical systems, such as for IVI application isolation.

Hypervisors, however, can meet all these requirements and are also optimized for particular multi-core SoCs. “Virtualization provides the best performance in terms of security, isolation and overhead when supported directly by the hardware platform,” says the white paper.

For hypervisors, the open source options listed by EG-VIRT include Xen, Kernel-based Virtual Machine (KVM), the L4Re Micro-Hypervisor, and ACRN. The latter was announced as a new Linux Foundation embedded reference hypervisor project in March. The Intel-backed, BSD-licensed ACRN hypervisor provides workload prioritization and supports real-time and safety-criticality functions. The lightweight ACRN supports other embedded applications in addition to automotive.

Commercial hypervisors that will likely receive support in the AGL virtualization stack include the COQOS Hypervisor SDK, SYSGO PikeOS, and the Xen-based Crucible and Nautilus. The latter was first presented by the Xen Project as a potential solution for AGL virtualization back in 2014. There’s also the Green Hills Software Integrity Multivisor. Green Hills announced AGL support for Integrity earlier this month.

Unlike hypervisors, system partitioners do not tap specific virtualization functions within multi-core SoCs, and instead run as bare-metal solutions. Only two open source options were listed: Jailhouse and the Arm TrustZone based Arm Trusted Firmware (ATF). The only commercial solution included is the TrustZone based VOSYSmonitor.

In conclusion, EG-VIRT notes that this initial list of potential virtualization solutions is “non-exhaustive,” and that “the role of EG-VIRT has been defined as virtualization technology integrator, identifying as key next contribution the development of a communication bus reference implementation…” In addition: “Future EG-VIRT activities will focus on this communication, on extending the AGL support for virtualization (both as a guest and as a host), as well as on IO devices virtualization (e.g., GPU).”

Download the free white paper to learn more and join us at Open Source Summit + Embedded Linux Conference Europe in Edinburgh, UK on October 22-24, 2018, for 100+ sessions on Linux, Cloud, Containers, AI, Community, and more.

Linux Shutdown Command

In this tutorial, we will show you how to use the shutdown utility through practical examples and detailed explanations of the most common shutdown options.

The shutdown command brings the system down in a secure way. When the shutdown is initiated, all logged-in users and processes are notified that the system is going down, and no further logins are allowed. You can shut down your system immediately or at the specified time.

Shutdown Command Syntax

Before going into how to use the shutdown command, let’s start by reviewing the basic syntax.

The shutdown utility expressions take the following form:

shutdown [OPTIONS] [TIME] [MESSAGE]
  • optionsShutdown options such as halt, power-off (the default option) or reboot the system.
  • time – The time argument specifies when to perform the shutdown process.
  • message – The message argument specifies a message which will be broadcast to all users.

Read more at Linuxize.com

Decreasing Vulnerabilities Seen in Red Hat Linux

As usual there’s been a flurry of activity in the cloud and DevOps security space recently. In case you missed it, a particularly painful flaw was found in Red Hat Enterprise Linux’s DHCP (Dynamic Host Configuration Protocol) service not long ago.

The bug specifically affects RHEL 6 and 7 (and derivative OS, Fedora 28, apparently). The CVE folks allocated the following ID to it in case you want to look it up: CVE-2018-1111. What’s important to note about this discovery is that DHCP (the service which asks a DHCP server for a (usually) temporary IP address and then binds it to one of the host’s network interfaces) is a sometimes forgotten cornerstone of our current tech stacks. Amazon’s EC2 for example shouts out to a DHCP server whenever an instance is spun up. As well as asking for an IP address, your servers will  usually pick up DNS servers from DHCP requests, too.

A descendant of BOOTP, a similar service from a time gone by, the pervasive DHCP bug is commonly used on your home networks, your mobile networks and beyond. According to Red Hat the bug affects the “dhclient”, in tandem with the “NetworkManager” daemon, and means that “A malicious DHCP server, or an attacker on the local network able to spoof DHCP responses, could use this flaw to execute arbitrary commands with root privileges on systems using NetworkManager and configured to obtain network configuration using the DHCP protocol.”

At first glance, this vulnerability might make the RHEL naysayers complain that there’s yet another security issue that only affects Red Hat and not other Linux flavors. And, that must therefore mean that the other distributions are better at securing their packages. However, they couldn’t be more wrong.

The commercial model that Red Hat Inc offer is based around supporting enterprises with their products, on a paid-for basis, along with some consultancy on top for good measure. They’ve been very successful and now their products are in use globally on many mission critical opensource server estates. Why is this relevant? Well, aside from the fact that the (free) CentOS Linux flavour benefits from the downstream improvements made by Red Hat, the community as a whole does in addition.

I normally find that it’s hard to know who to believe when a lofty claim is made in the relatively congested Internet giants’ space,  However, a report published in November 2017 — called “The State of Open Source Security” — shows some evidence that Red Hat’s Linux might be ruling the roost for security currently. Obviously, I can’t make any guarantees for the report’s impartiality.

Commissioned by Snyk, the report states: “Open source library vulnerabilities increased by 53.8% in 2016, while Red Hat Linux vulnerabilities have decreased.” The report is well-constructed and easy to digest and, as a plumb line to what’s going on the with security on the Internet in general, it’s a welcome read. It states that there’s been a “65% decrease in Red Hat vulnerabilities since 2012” and in addition to that: “In 2016, 69% of Red Hat Linux vulnerabilities were fixed within a day of their public disclosure, and 90% were fixed within 14 days of their public disclosure”.

The report continues: “Red Hat Linux seems to be finding some level of stability” and “…it does make us optimistic that better security is achievable with a little bit of work”.

The truth, of course, is that every device or service has a vulnerability of some description or another, and, as the report states, “there are a lot of steps involved in the lifecycle of an open source security vulnerability. From discovery through final adoption of fixes, each part of the process is important in its own way, and ultimately plays a role in the overall state of security.” Code auditing is key as well as timely response to vulnerabilities. Check out the report to learn more.

Chris Binnie’s latest book, Linux Server Security: Hack and Defend, shows how hackers launch sophisticated attacks to compromise servers, steal data, and crack complex passwords. In the book, he also shows you how to make your servers invisible, perform penetration testing, and mitigate unwelcome attacks. You can find out more about DevOps, DevSecOps, Containers, and Linux security on his website: https://www.devsecops.cc.

Over 20,000 Container Management Dashboards Are Exposed on the Internet

Even though it’s highly discouraged to expose any kind of management dashboard directly to the internet, there are many users who continue to ignore this recommendation, and it seems that infrastructure admins are no exception.

A recent study by cloud security firm Lacework found over 22,000 publicly exposed container orchestration and API management systems, about 300 of which could be accessed without any credentials and gave attackers full control or remote code execution capability on containers.

Kubernetes dashboards accounted for over 75 percent of the exposed interfaces, followed by Docker Swarm (Portainer and Swarmpit) with 20 percent, Swagger API UI with 3 percent and Mesos Marathon and Red Hat OpenShift with under 1 percent each.

Read more at The New Stack

Open Source at 20: The Ubiquity of Shared Code

“Why is open source important? That’s like asking why is gravity important,” stated Brian Behlendorf, a leading figure in the open-source software movement, and executive director for the blockchain consortium Hyperledger.

While this year marks the 20th anniversary of open source, it is hard to imagine a time before open-source software. Today, it’s difficult to find a solution or piece of software that was created without some open-source components….

Behlendorf recalls first being attracted to the open-source space because he didn’t really trust his own coding abilities, and the idea that there were other developers out there willing to read his code and help him fix it was a “godsend.” “For many people who became programmers after the ‘90s, working publicly, pulling down open-source code, sharing improvements back if you made any or even taking your work and releasing it pubilicy became the default. It was what was expected,” he said.

However, being able to share and collaborate openly on software wasn’t always possible. OSI’s vice president VM Brasseur describes the early days as the “wild west” where programmers were building tools for programmers, driven by the philosophical belief that “sharing is good and right.”

Read more at SDTimes

​The Linux Mint Desktop Continues to Lead the Rest

You can keep your Windows 10 and macOS High Sierra. For me, Linux Mint 19 is not only the best Linux desktop, it’s the best desktop. Period. End of statement.

Why? Because its traditional windows, icons, menus, and pointers (WIMP) interface is a true pleasure to use. It’s even more fun now, because with Mint 19 and its default Cinnamon 3.8 desktop it’s faster and snappier than ever. The Cinnamon desktop, which uses the GTK 3.22 toolkit, also has a smoother look than previous versions.

Linux, as ever, out of the box is more secure than macOS or Windows even after you strap on all the anti-virus software. On my Mac and Windows boxes, security is an almost daily job of patches and fixes. On my Mint desktops? I don’t even worry about it and I have never had a single security problem. I wish I could say the same about the competing operating systems.

Read more at ZDNet

How to Plan Projects in the Open, Without the Stress

How can you define project requirements, engage multiple stakeholders, delegate work, and track progress—all in the open? Here’s one tried-and-true method.

Consider these questions:

  • How do you gather and understand requirements?
  • How do you track those requirements?
  • How do you map them into real work that someone can deliver?
  • How do you clarify when the work should be completed, what success looks like, and who is involved?
  • How do you track all this without bogging down your execs (or your teams) with too much detail

Watch the video at OpenSource.com to learn more.

Big O Notation? More like Big O-M-G

There are a lot of ways to write algorithms for a specific task. Since there are so many variations, how does someone know which algorithm to use in which situation? One way to look at the problem is to ask yourself: what limitations are present and how can I check if the algorithm fits within these constraints? Big O is used to help identify which algorithms fit inside these constraints and limitations.

Big O notation is a mathematical representation of how an algorithm scales with an increasing number of inputs. In other words: the length of time it takes for a certain algorithm to run or how much space it will consume during computations.

By using Big O notation, developers and engineers can construct the best algorithm that fits within their constraints.

How does Big O work?

So, Big O is used to describe the trend of an algorithm, but what does the language surrounding Big O sound like? In conversation, you would talk about Big O like this: “The time complexity of [a certain algorithm] is O(n) — “O of n” (both “O” and “n” are pronounced like the letter). The reason I am using the phrase time complexity is because Big O notations are most commonly referred to as time complexities. “n” is used in Big O to refer to the number of inputs. There is another side to Big O called space complexity but I’ll talk about that later in the blog.

Now that you know how to talk about Big O and what it’s used for, let’s look at some examples to help you understand how Big O is calculated. The following examples will go over some of the more common Big O notations you will see (in order): O(n)O(log(n))O(n^2)O(1).


Time complexity: O(n)

1*g5D_dsEo__lYJIkEc_sEmg.jpeg

“Could you not?”

Let’s say that someone stole the last cookie out of your cookie jar (“how rude!”), and you really wanted to eat that cookie, so now you have to go out and find it. One way you could go about to find the cookie is to ask your 5 friends, one by one, if they took your cookie. We could represent this as a function in Python3:

>>> def who_has_my_cookie(my_friends):
...     for friend in my_friends:
...         if friend.get('has_cookie'):
...             return friend.get('name')

In this function, you are going to go ask each of your friends if they have your cookie. In this case, the length of my_friends is your n. This function’s run time is dependent on how many friends were present during the abduction. For that reason, this function would have a time complexity of O(n).

Now let’s feed the function some input, and see who took the cookie:

>>> my_friends = [
...     {'name':'Kristen', 'has_cookie':False},
...     {'name':'Robert', 'has_cookie':False},
...     {'name':'Jesse', 'has_cookie':False},
...     {'name':'Naomi', 'has_cookie':False},
...     {'name':'Thomas', 'has_cookie':True}
... ]
>>> cookie_taker = who_has_my_cookie(my_friends)
>>> print(cookie_taker)
Thomas

You might wonder, “But what if the first person you ask has the cookie?” Great question! In that case, the time complexity would be O(1), also known as constant time. Even so, the time complexity for this problem would still be O(n).

Why is the correct notation O(n)? In most cases, you won’t get the best case scenario — i.e. finding the cookie on the first person. This means it’s best to think of the worst case scenario when dealing with algorithms.

Summary of O(n): A loop that could iterate the same amount of times as the max number of input. In the case above, the loop goes through 5 iterations, of which there were 5 friends (my_friends) before finding who stole your cookie.


Time Complexity: O(log(n))

In this next scenario, lets say that you had all of your friends line up side by side. You then find the middle person and ask them if the cookie is on their left side or right side. You then find the middle person on that side and ask them the same thing — using the original middle person as a boundary to search smaller portions of the line. This keeps happening until the person who has the cookie is found. This can be written in Python3:

>>> def search_for_cookie(my_friends, first, last):
...     middle = (last - first) // 2 + first
...     middle_response = my_friends[middle].get('where_is_cookie')
...     if middle_response is 'I have it':
...         return my_friends[middle].get('name')
...     elif middle_response is 'to the right':
...         # Search on the right half
...         return search_for_cookie(my_friends, middle + 1, last)
...     else:
...         # Search on the left half
...         return search_for_cookie(my_friends, first, middle - 1)

In this function, first refers to the first person in the section being looked at — the first time, the section you’ll be looking at is the whole line. last refers to the last person in the section being looked at and middle refers to the person in the middle in between first and last.

This function would keep going until the person that has your cookie has been singled down. Looking at the worst case scenario, this function wouldn’t find out who has the cookie until the person has been singled out on the last run. This means the function has a time complexity of O(log(n)).

Let’s feed this function some input and see who took your cookie:

>>> my_friends = [
...     {'name':'David', 'where_is_cookie':'to the right'},
...     {'name':'Jacob', 'where_is_cookie':'to the right'},
...     {'name':'Julien', 'where_is_cookie':'to the right'},
...     {'name':'Dimitrios', 'where_is_cookie':'I have it'},
...     {'name':'Sue', 'where_is_cookie':'to the left'}
... ]
>>> cookie_taker = search_for_cookie(my_friends, 0, len(my_friends) ... - 1)
>>> print(cookie_taker)
Dimitrios

Summary of O(log(n))When a function cuts the section you’re looking at by half every iteration, you can suspect an O(log(n)) algorithm. Spotting this kind of behavior along with incrementing using i = i * 2 for each iteration allows for simple diagnosis. This way of narrowing down who has the cookie is typical of recursive functions like quick sort, merge sort and binary searches.


Time Complexity: O(n^2)

In this next scenario, let’s say that only one person knows who took your cookie and only by name. The person who took the cookie won’t fess up to it either, so you have to name off each other friend to the friend you are talking to. This can be written in Python3:

>>> def who_has_my_cookie(my_friends):
...     for friend in my_friends:
...         for their_friend in friend.get('friends'):
...             if their_friend.get('has_cookie'):
...                 return their_friend.get('name')

If you imagine yourself in this situation you can see that it’s going to take a lot longer than any of the other situations because you need to keep reciting everyone’s name every time you go to the next friend.Worst case scenario, you need to cycle through each friend and ask them about every other friend. If you look at the loops, you can see that the outer loop has a time complexity of O(n), and the inner loop also has a time complexity of O(n). This means the function will have a time complexity of O(n^2) because you multiply the time complexities together O(n * n).

Let’s feed this function some input and see who took your cookie:

>>> my_friends = [
...     {'name':'Steven', 'friends':[
...         {'name':'Steven', 'has_cookie':False},
...         {'name':'Binita', 'has_cookie':False},
...         {'name':'Linds', 'has_cookie':False},
...         {'name':'Raman', 'has_cookie':False},
...         {'name':'Elaine', 'has_cookie':False}
...         ]
...     },
...     {'name':'Binita', 'friends':[
...         {'name':'Steven', 'has_cookie':False},
...         {'name':'Binita', 'has_cookie':False},
...         {'name':'Linds', 'has_cookie':False},
...         {'name':'Raman', 'has_cookie':False},
...         {'name':'Elaine', 'has_cookie':False}
...         ]
...     },
...     {'name':'Linds', 'friends':[
...         {'name':'Steven', 'has_cookie':False},
...         {'name':'Binita', 'has_cookie':False},
...         {'name':'Linds', 'has_cookie':False},
...         {'name':'Raman', 'has_cookie':False},
...         {'name':'Elaine', 'has_cookie':False}
...         ]
...     },
...     {'name':'Raman', 'friends':[
...         {'name':'Steven', 'has_cookie':False},
...         {'name':'Binita', 'has_cookie':False},
...         {'name':'Linds', 'has_cookie':False},
...         {'name':'Raman', 'has_cookie':False},
...         {'name':'Elaine', 'has_cookie':False}
...         ]
...     },
...     {'name':'Elaine', 'friends':[
...         {'name':'Steven', 'has_cookie':False},
...         {'name':'Binita', 'has_cookie':False},
...         {'name':'Linds', 'has_cookie':False},
...         {'name':'Raman', 'has_cookie':True},
...         {'name':'Elaine', 'has_cookie':False}
...         ]
...     }
... ]
>>> cookie_taker = who_has_my_cookie(my_friends)
>>> print(cookie_taker)
Raman

Summary of O(n^2): There is a loop within a loop, so you could instantly think that it would be O(n^2). That’s a correct assumption, but to make sure, double check and make sure the increments are still being incremented ntimes. Some loops within loops turn out to be O(nlog(n)).


Time Complexity: O(1)

In this next scenario, let’s assume that you have a security camera that is watching your jar of cookies at all times. Once you noticed that your cookie was missing, you check the tapes and know exactly who took your cookie. For this reason, you can immediately go to that person and get the cookie back. This can be written in Python3:

>>> def who_has_my_cookie(my_friends, security_camera):
...     return my_friends[security_camera].get('name')

This would be considered a time complexity of O(1) because no matter who took your cookie, it would always result in the same amount of time being spent getting it back.

Let’s feed this function some input and expose the cookie thief:

>>> my_friends = [
...     {'name':'Sid', 'has_cookie':False},
...     {'name':'Guillaume', 'has_cookie':False},
...     {'name':'Lee', 'has_cookie':False},
...     {'name':'Liz', 'has_cookie':False},
...     {'name':'Kevin', 'has_cookie':True}
... ]
>>> cookie_taker = who_has_my_cookie(my_friends, 4)
>>> print(cookie_taker)
Kevin

Summary of O(1): If a function has no loops, and only performs one thing based off of the input you are giving, it’s usually going to be an O(1) time complexity.


There’s one more thing about Big O notations that you need to know. Constants in Big O are thrown out. The reasoning behind this is that once the number of inputs become large enough, the constants don’t really give any meaningful insights into the time complexity anymore.

Nested Loops vs Non-Nested Loops

When there is a nested loop, you multiply them together. In the O(n^2)example above, there was a loop within a loop giving the time complexity O(n^2). If there is a loop right after another loop, (not nested), you would add them together rather than multiply. This would give a time complexity of O(n + n) which can be combined to produce O(2n). You know now that Big O notations get rid of any constants, so that would reduce down into O(n).

But what if there was another set of inputs that aren’t as long or short as n? You can represent that set of inputs as k. Say you have a nested loop with nas the outer loop and k as the inner loop. This would boil down to O(n*k). You can’t really simplify it to be O(n^2) since k is not the same as n, so O(n*k) is the correct notation. Same goes for non-nested loops: O(n + k).


If you are a visual learner, I have included a graph to help you spot which algorithm is taking more time than other algorithms. You can clearly see that any of the polynomial notations ( n!2^nn^2 ) are generally going to take a lot longer than say, log(n).

 
1*lLbL3VCKkKbf-Y_dVbB5-Q.png

N is computation time and n is number of input elements

Some of the other types of time complexities that exist, but are not described in this blog are:

  1. O(n!) — O of n factorial
  2. O(2^n) — O of 2 to the n
  3. O(nlog(n)) — O of n log n: Example
  4. O(sqrt(n)) — O of square root of n

Feel free to look up these more complex Big O notations.

Space Complexity

There is also another side to Big O. Instead of focusing on time only, a different aspect can also be inspected — Space complexity. Space complexity is a measure of the amount of working storage an algorithm needs during run time.

In this scenario, let’s say that all your friends are in different rooms and you need to keep track of who you’ve talked to so you don’t ask the same person twice. This can be written in Python3:

>>> def who_took_my_cookie(my_friends):
...     spoken_to = []  
...     for friend in my_friends:
...         if friend not in spoken_to:
...             if friend.get('has_cookie'):
...                 print(spoken_to)
...                 return friend.get('name')
...             else:
...                 spoken_to.append(friend.get('name')

In this example, the spoken_to list could be as long as there are total friends. This means that the space complexity is O(n).

Let’s feed this function some input and see who took your cookie:

>>> my_friends = [
...     {'name':'Kristen', 'has_cookie':False},
...     {'name':'Robert', 'has_cookie':False},
...     {'name':'Jesse', 'has_cookie':False},
...     {'name':'Naomi', 'has_cookie':False},
...     {'name':'Thomas', 'has_cookie':True}
... ]
>>> cookie_taker = who_has_my_cookie(my_friends)
['Kristen', 'Robert', 'Jesse', 'Naomi']
>>> print(cookie_taker)
Thomas

Summary of Space Complexity: Space complexity can have as many notations as time complexity. This means that the O(n^2), etc. also exists and can be calculated using the same general principles. Be careful though, time and space complexities may be different than each other for a given function.

By combining time complexity with space complexity, you can begin to compare algorithms and find which one will work best for your constraints.

Battle of the Algorithms

1*-0kWkkgpkBi4VywaovVwqA.jpeg

“Which algorithm will win?!”

Now that you know what time and space complexities are and how to calculate them, let’s talk about some cases where certain algorithms may be better than others.

A simple example to clearly define some constraints would be to examine a self-driving car. The amount of storage in the car is finite — meaning that there is only so much memory that can be used. Because of this, algorithms which favor low space complexity are often favored. But in this case, fast time complexities are also favored, which is why self-driving cars are so difficult ot implement.

Now let’s examine something like a cellphone. The same storage limitations are in place, but because the cellphone isn’t driving around on the street, some sacrifices in time complexity can be made in favor of less space complexity.


Now that you have the tools to start computing the time and space complexity of the algorithms you read and write, determine which algorithm is best for your constraints. Determining which algorithm to use must take into consideration the space available for working memory, the amount of input to be parsed, and what your function is doing. Happy Coding!

Finding IT Professionals With SDN Skills Remains a Struggle

With any major technology transition there is a gap between the time when the innovation is created and when there is a critical mass of IT professionals available with training and knowledge on how to deploy that state-of-the-art technology.

Although software-defined networking (SDN) and network functions virtualization (NFV) technology has been around for quite some time, network engineers are still reluctant to adopt the technology.

Plus, there are many different technologies that make up the SDN/NFV ecosystem, which means there are a number of different technologies that require training, said Eric Hanselman, chief analyst for 451 Research. Without a dominant set of SDN and NFV technologies, network administrators are unsure what combination of technologies they need to master. And this comes at a time when network services are becoming more disaggregated, Hanselman noted.

Plus, most companies are conservative when making major changes to their networks because if something goes wrong there is the potential for a ‘blast radius,’ which could become a huge problem, Hanselman said.  “The entire scope of the endeavor can be huge,” he added.

Read more at SDxCentral