Versão word

parent 6261e934
\section{Introduction}
\label{sec:intro}
\devops aims to enable the adoption of continuous delivery and to facilitate management within organizations.
It achieves this goal primarily via automation and human collaboration across the organization. This approach allows each software increment to be deployable into the production environment by the press of a single button~\cite{humble2010continuous}, and each update comply with functional and non-functional software requirements.
From the process perspective, \devops is a natural evolution of the agile movement~\citesel{christensen2016teaching}.
Agile Software Development advocates small release iterations with customer reviews. It assumes the team can release software frequently in some production-like environment. However, the initial Agile literature puts little emphasis on deployment-specific practices.
No Extreme Programming (XP) practice, for example, is about deployment~\cite{beck2004xp}.
The same little attention to deployment is perceived in traditional software engineering processes~\cite{kroll2003rup} and books~\cite{pressman2005software,sommerville2011software}. Consequently, the transition to production tends to be a tense process in organizations, containing manual, error-prone activities and, even, last-minute corrections~\cite{humble2010continuous}.
\devops aims to solve this problem by proposing a set of practices to effectively enable the iterative delivery of software in short cycles.
From the organization perspective, \devops can be seen as the movement to change the structure of teams to promote a closer collaboration between developers and operators. The existence of distinct departments/silos for operations and development is still common. Operations staff is responsible for managing software changes in production and for its service levels~\citesel{woods2016view}. Development teams, on the other hand, are responsible for developing continuously new features to meet business requirements. It is common to each one of these departments to have its own independent processes, tools, and knowledge bases. The interface between them, in the pre-\devops era, is usually a ticket system, in which development teams demand the deployment of new software versions, and the operations staff processes such tickets manually. This structure was meant to provide high stability for software in production, but it also resulted in very long delays between code updates and deployment.
In such structure, development teams continuously try to push new versions into production to satisfy business-functional needs. Operations staff, contrarily, try to block these changes to maintain software stability and other non-functional concerns. This structure leads to ineffective problem-solving processes, since the different organizational silos keep blaming each other for production problems.
Issues like conflicts between developers and operators, significant deployment times, and the need for frequent and reliable releases led to an inefficient agile execution. Therefore, developers and operators started a collaboration movement within enterprises to address this gap. This movement was coined as \devops in 2008~\cite{debois2008devops}.
From the technical perspective, many authors closely relate \devops to continuous delivery and deployment~\citesel{shahin2016architecting,wettinger2015environments,yasar2016security,wettinger2015knowledge}.
In the \emph{Continuous Delivery} book~\cite{humble2010continuous}, Humble advocates the usage of an \emph{automated deployment pipeline}: any software version committed to the repository must be a production-candidate version; but before it is declared ready for production, it must pass through the pipeline stages, such as compilation and automated tests. After such stages, software is ready to go to production by the pressing of a button. This process is called the \emph{continuous delivery}. A step further is automatically sending to production every version that passes through the pipeline, and it is called \emph{continuous deployment}~\cite{humble2010deployment}. What Yasar, for example, calls a ``DevOps platform''~\citesel{yasar2016security}, is actually the deployment pipeline.
Besides automating the delivery process, \devops initiatives have also focused on the usage of automated runtime monitoring for improving software runtime properties, such as performance, scalability, availability, and resilience~\citesel{christensen2016teaching,basiri2016chaos,balalaie2016microservices,roche2013quality}. From this view, ``Site Reliability Engineering''~\cite{beyer2016site} emerged as a new term related to the \devops work at runtime.
Yearning for improvements in organizational performance~\cite{puppet2014devops}, enterprises are widely adopting \devops~\citesel{chen2015huge,gray2006conversation,feitelson2013facebook}. The word ``\devops'' has also become a role in the software industry~\citesel{hussain2017zealand}, and a well paid-one~\cite{stackoverflow2017earn}. In this context, becoming a \devops expert is an attractive option for software professionals. \devops is also an important phenomenon to be studied by software engineering researchers and already a mandatory topic to be taught in software engineering courses.
Even though the \devops movement has being discussed for nearly a decade now, there is no consensual definition for the term \devops.
Based on the presented historical discussion and on an extensive survey of the literature, we combined the most cited definitions of \devops and crafted the following definition that we adopt throughout this paper:
\begin{quotation}
\emph{\devops is a collaborative and multidisciplinary effort within the organization
aiming at automating continuous delivery of new software versions,
while guaranteeing their correctness and reliability.}
\end{quotation}
\noindent In particular, our definition is very close to the one proposed by Dyck \emph{et al.}~\citesel{dyck2015release}.
\devops and its challenges can be treated from three different perspectives: Engineers, Managers, and Researchers. Each perspective focuses on different \emph{\devops challenges} and has different participation and contribution for a given \emph{\devops challenge}. \textbf{Engineers} profit from \textbf{1)} qualifying themselves for a \devops position, which is a technically hard task, given the existence of over 200 papers, 140 books, and 100 tools~\cite{xebia2016table} related to the subject. Engineers also need to \textbf{2)} learn how to re-architect their systems to enable the adoption of continuous delivery. \textbf{Managers} want to know mainly \textbf{3)} how to deploy \devops in their organizations, and \textbf{4)} how to assess the quality of \devops practices already established in their organizations. Finally, academic \textbf{researchers} \textbf{5)} conduct studies to assess the state of the practice in \devops, contributing to open discussions among engineers and managers, and \textbf{6)} educate a new generation of software engineers for \devops principles and practices.
Nonetheless, the answer for each \devops challenge can involve all three perspectives. For example, although the adoption of \devops in the enterprise concerns mainly managers, it also requires high involvement of engineers and it is also a frequent research topic. Managers and engineers together are also referred as practitioners to emphasize their shared concerns. Teaching \devops, for instance, must take into account the engineer's learning perspective, but it is also a managerial issue since the enterprise should adopt an educational strategy concerning \devops adoption.
There are several studies and a few surveys tackling \devops challenges. However, with few exceptions~\citesel{neely2013easy}, they usually focus on a single perspective when addressing a given challenge.
%The primary example is the challenge of studying strategies for \devops adoption, which are focused mainly on the managerial perspective.
In this context, \emph{this survey contributes to the field by investigating and discussing \devops challenges from the multiple perspectives: engineers, managers, and researchers}. Our survey explores a much broader range of sources and it is more up to date than previous studies. We summarize and discuss the main findings reported by the existing literature regarding these challenges, and we point out limitations and even contradictions in the literature.
We start by outlining the methodology of this study in Section~\ref{sec:methodology}. We, then, reveal our sources in Section~\ref{sec:sources}, from which follows, in Section~\ref{sec:concepts}, the construction of conceptual maps based on these sources, which lays out the basis of our analysis. We, then, discuss the \devops toolset in Section~\ref{sec:tools}, relating the main existing tools to \devops concepts. We draw implications of \devops concepts and practices for engineers, managers, and researchers in Section~\ref{sec:implications}, and we discuss critically some of the most relevant \devops challenges revealed by our sources of knowledge in Section~\ref{sec:discussion}. Finally, we state the limitations of this survey in Section~\ref{sec:limitations} and draw our final remarks in Section~\ref{sec:conclusions}.
%However, with the multitude of works published on \devops, about 200 papers and 140 books, it is hard for one to decide how to start their path to become a \devops expert. There are also more than 100 \devops tools~\cite{xebia2016table}. Clearly becoming a \devops expert does not mean reading every text on \devops or learning how to use every \devops tool. In this context, \emph{the goal of this paper is to guide engineers and researchers through the main sources of knowledge, readings, concepts, and tools one should know to achieve \devops-related goals}.
Introduction
sec:intro
aims to enable the adoption of continuous delivery and to facilitate management within organizations.
It achieves this goal primarily via automation and human collaboration across the organization. This approach allows each software increment to be deployable into the production environment by the press of a single button humble2010continuous, and each update comply with functional and non-functional software requirements.
From the process perspective, is a natural evolution of the agile movement christensen2016teaching.
Agile Software Development advocates small release iterations with customer reviews. It assumes the team can release software frequently in some production-like environment. However, the initial Agile literature puts little emphasis on deployment-specific practices.
No Extreme Programming (XP) practice, for example, is about deployment beck2004xp.
The same little attention to deployment is perceived in traditional software engineering processes kroll2003rup and books pressman2005software,sommerville2011software. Consequently, the transition to production tends to be a tense process in organizations, containing manual, error-prone activities and, even, last-minute corrections humble2010continuous.
aims to solve this problem by proposing a set of practices to effectively enable the iterative delivery of software in short cycles.
From the organization perspective, can be seen as the movement to change the structure of teams to promote a closer collaboration between developers and operators. The existence of distinct departments/silos for operations and development is still common. Operations staff is responsible for managing software changes in production and for its service levels woods2016view. Development teams, on the other hand, are responsible for developing continuously new features to meet business requirements. It is common to each one of these departments to have its own independent processes, tools, and knowledge bases. The interface between them, in the pre-era, is usually a ticket system, in which development teams demand the deployment of new software versions, and the operations staff processes such tickets manually. This structure was meant to provide high stability for software in production, but it also resulted in very long delays between code updates and deployment.
In such structure, development teams continuously try to push new versions into production to satisfy business-functional needs. Operations staff, contrarily, try to block these changes to maintain software stability and other non-functional concerns. This structure leads to ineffective problem-solving processes, since the different organizational silos keep blaming each other for production problems.
Issues like conflicts between developers and operators, significant deployment times, and the need for frequent and reliable releases led to an inefficient agile execution. Therefore, developers and operators started a collaboration movement within enterprises to address this gap. This movement was coined as in 2008 debois2008devops.
From the technical perspective, many authors closely relate to continuous delivery and deployment shahin2016architecting,wettinger2015environments,yasar2016security,wettinger2015knowledge.
In the Continuous Delivery book humble2010continuous, Humble advocates the usage of an automated deployment pipeline: any software version committed to the repository must be a production-candidate version; but before it is declared ready for production, it must pass through the pipeline stages, such as compilation and automated tests. After such stages, software is ready to go to production by the pressing of a button. This process is called the continuous delivery. A step further is automatically sending to production every version that passes through the pipeline, and it is called continuous deployment humble2010deployment. What Yasar, for example, calls a ``DevOps platform'' yasar2016security, is actually the deployment pipeline.
Besides automating the delivery process, initiatives have also focused on the usage of automated runtime monitoring for improving software runtime properties, such as performance, scalability, availability, and resilience christensen2016teaching,basiri2016chaos,balalaie2016microservices,roche2013quality. From this view, ``Site Reliability Engineering'' beyer2016site emerged as a new term related to the work at runtime.
Yearning for improvements in organizational performance puppet2014devops, enterprises are widely adopting chen2015huge,gray2006conversation,feitelson2013facebook. The word ``has also become a role in the software industry hussain2017zealand, and a well paid-one stackoverflow2017earn. In this context, becoming a expert is an attractive option for software professionals. is also an important phenomenon to be studied by software engineering researchers and already a mandatory topic to be taught in software engineering courses.
Even though the movement has being discussed for nearly a decade now, there is no consensual definition for the term .
Based on the presented historical discussion and on an extensive survey of the literature, we combined the most cited definitions of and crafted the following definition that we adopt throughout this paper:
quotation
is a collaborative and multidisciplinary effort within the organization
aiming at automating continuous delivery of new software versions,
while guaranteeing their correctness and reliability.
quotation
In particular, our definition is very close to the one proposed by Dyck et al. dyck2015release.
and its challenges can be treated from three different perspectives: Engineers, Managers, and Researchers. Each perspective focuses on different challenges and has different participation and contribution for a given challenge. Engineers profit from 1) qualifying themselves for a position, which is a technically hard task, given the existence of over 200 papers, 140 books, and 100 tools xebia2016table related to the subject. Engineers also need to 2) learn how to re-architect their systems to enable the adoption of continuous delivery. Managers want to know mainly 3) how to deploy in their organizations, and 4) how to assess the quality of practices already established in their organizations. Finally, academic researchers 5) conduct studies to assess the state of the practice in , contributing to open discussions among engineers and managers, and 6) educate a new generation of software engineers for principles and practices.
Nonetheless, the answer for each challenge can involve all three perspectives. For example, although the adoption of in the enterprise concerns mainly managers, it also requires high involvement of engineers and it is also a frequent research topic. Managers and engineers together are also referred as practitioners to emphasize their shared concerns. Teaching , for instance, must take into account the engineer's learning perspective, but it is also a managerial issue since the enterprise should adopt an educational strategy concerning adoption.
There are several studies and a few surveys tackling challenges. However, with few exceptions neely2013easy, they usually focus on a single perspective when addressing a given challenge.
In this context, this survey contributes to the field by investigating and discussing challenges from the multiple perspectives: engineers, managers, and researchers. Our survey explores a much broader range of sources and it is more up to date than previous studies. We summarize and discuss the main findings reported by the existing literature regarding these challenges, and we point out limitations and even contradictions in the literature.
We start by outlining the methodology of this study in Section sec:methodology. We, then, reveal our sources in Section sec:sources, from which follows, in Section sec:concepts, the construction of conceptual maps based on these sources, which lays out the basis of our analysis. We, then, discuss the toolset in Section sec:tools, relating the main existing tools to concepts. We draw implications of concepts and practices for engineers, managers, and researchers in Section sec:implications, and we discuss critically some of the most relevant challenges revealed by our sources of knowledge in Section sec:discussion. Finally, we state the limitations of this survey in Section sec:limitations and draw our final remarks in Section sec:conclusions.
\section{Methodology}
\label{sec:methodology}
Although tools and concrete techniques are essential, we focus only on the primary tools leveraged by the \devops movement. We do not discuss every tool or academic work about automated deployment~\cite{wettinger2013tosca,leite2014deploying}. Automated deployment has a long line of works~\cite{magee1996dynamic,magee1994regis} and discussing each approach does not sum up to illuminate the path of a \devops expert.
This diff is collapsed.
\section{Fundamental \devops Concepts}
\label{sec:concepts}
In this section, we present the \emph{fundamental concepts on \devops} emerged from our literature review. These fundamental concepts are organized and presented as conceptual maps, which are diagrams depicting suggested relationships between concepts~\cite{hager1997designing}.
The \emph{objective} of our conceptual maps is \emph{to provide a relevant and structured set of concepts on \devops, grounded on the literature, to support the analysis of \devops challenges}.
\subsection{Producing the conceptual maps}
The process of building the conceptual maps was based on Grounded Theory strategies. Grounded Theory is a major method for conducting emergent qualitative research~\cite{charmaz2008grounded} and it is also considered an appropriate research method to explore the human and social aspects of Software Engineering~\cite{hoda2011grounded}. According to Charmaz, it minimizes preconceived ideas about the research problem and it helps researchers to remain open to different explanations and understandings of the data~\cite{charmaz2008grounded}. It usually is applied to primary sources, such as interviews and field-notes of observations~\cite{hoda2011grounded, sbaraini2011grounded}, not on literature articles. In the present work, Grounded Theory strategies were only used to support the definition of a rigorous analysis process to handle the intrinsic subjectivity of our conceptual analysis.
%Nonetheless, we must make clear we do not claim to be using Grounded Theory itself in this work since our objective is not to produce a new theory based on our sources. Moreover,
A core strategy of Grounded Theory is \emph{coding}~\cite{charmaz2008grounded}, which is a process of breaking data down into much smaller components and labeling those components~\cite{sbaraini2011grounded}. The codes, arising out of different sources, are compared continuously among each other to produce units of a higher level of abstraction, called \emph{concepts}, and the concepts themselves are compared and grouped to produce a third level of abstraction called \emph{categories}~\cite{hoda2011grounded}. In our study, we carried the full read of \numberofmainselectedpapers selected studies to produce the codes. After this, we analyzed, abstracted and grouped the codes into concepts. Finally, by analyzing the concepts and their relations, we derived four categories of concepts, each one having its own conceptual map.
The process of building our conceptual maps followed the following rules and restrictions:
\begin{itemize}
\item Every concept and link must be supported by at least one selected study.
\item The label on the link corresponds to the \emph{``code''} of the reference. The codes are defined at the Main Selected Studies listing.
\item A link can have different labels, each one with its own references.
\item The labels in a single link can described by both antagonistic and similarity relations.
\item Some concepts, with common links, are grouped to save space in the figure.
\item The references on link labels are selected studies of our reviewed literature, even when the concepts and relations were originated from work cited by our selected studies.
\end{itemize}
The concepts were separated into four major categories: Process, People, Delivery, and Runtime. These categories are depicted on Figure~\ref{fig:concepts-families}.
\begin{figure}[ht]
\includegraphics[scale=0.4]{figs/concepts-categories}
\caption{\devops overall conceptual map}
\label{fig:concepts-families}
\end{figure}
The following subsections present one conceptual map for each of the listed categories.
\subsection{Process}
\devops deploys a continuous delivery \emph{process} to achieve business benefits. Reducing risk and cost, complying with regulations, improving product quality and customer satisfaction are samples of these benefits. We grouped those concepts into the \emph{process} category of concepts, and they are all related to the business outcome from \devops. Some concepts are not exclusively achieved by \devops approach. One could argue that rigorous human and hierarchical approval process is an option to reduce risk, comply with regulations, and provide product quality. The difference here is that the \devops approach is based on the agile mindset, which advocates the shortening of feedback cycle through frequent releases. The \emph{Process} category of concepts is presented in Figure \ref{fig:concepts-process}.
\begin{figure}[ht]
\includegraphics[scale=0.25]{figs/concepts-process}
\caption{Process conceptual map}
\label{fig:concepts-process}
\end{figure}
\subsection{People}
The term ``\devops'' itself centers around the idea of bringing together \emph{people} from development and operations through a culture of collaboration. The intention is avoiding distinct areas of the organization to have different and conflicting goals, which could reduce efficiency and time-to-market. However, breaking down the silos raises a lot of questions, such as: how to perform a cultural shift in the organization that implies more responsibilities for developers? How do developers acquire operations skills? Can developers and operators work in the same team and still keep different job titles? Should ``\devops'' be a role? Should teams be cross-functional and include operators? Should an operator be exclusive to one single team? What actually means being an operator in the \devops context? Although the concepts implied in such questions are frequent in the literature, the answers are not clear yet. We grouped these concepts in the \emph{people} category and we debate such questions in Section~\ref{sec:devosp-adoption-approaches}. The \emph{People} category of concepts is presented in Figure~\ref{fig:concepts-people}.
\begin{figure}[ht]
\includegraphics[scale=0.25]{figs/concepts-people}
\caption{People conceptual map}
\label{fig:concepts-people}
\end{figure}
\subsection{Delivery}
The core strategy for achieving a frequent and reliable delivery process is based on the automation of the \emph{deployment pipeline}, from which \devops tools and techniques emerge. We grouped the concepts surrounding the deployment pipeline into the \emph{delivery} category, which is a much more technical category than the previous ones. There is still some debate on concrete approaches for tooling, such as the containerized approach leveraged by Docker from one side, and continuous configuration convergence, such as in Chef and Puppet, on the other side. We discuss such debate in Section~\ref{sec:tools}. However, we claim that the \emph{delivery} concepts are much more stable and accepted by the community than the \emph{people} concepts. The \emph{Delivery} category of concepts is presented in Figure~\ref{fig:concepts-delivery}.
\begin{figure}[ht]
\includegraphics[scale=0.25]{figs/concepts-delivery}
\caption{Delivery conceptual map}
\label{fig:concepts-delivery}
\end{figure}
\subsection{Runtime}
\emph{Runtime} concepts are a subsequent and necessary extension in the \devops approach since it is not enough to continuously deliver new versions, but it is also necessary for each new version to be stable and reliable. The need for such reliability is the main link between the \devops approach and cloud environments. It is also worthy to note that while \emph{delivery} concepts are more related to developers, \emph{runtime} concepts are more related to the traditional operator role. The \emph{Runtime} category of concepts is presented in Figure~\ref{fig:concepts-runtime}.
\begin{figure}[ht]
\includegraphics[scale=0.25]{figs/concepts-runtime}
\caption{Runtime category of concepts}
\label{fig:concepts-runtime}
\end{figure}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
\section{Limitations}
\label{sec:limitations}
% based on the paper "A systematic literature review of service
% choreography adaptation" we have published on SOCA
Given the vast amount of work on \devops, we could not conduct an exhaustive search in every source. For example, we have not considered academic workshops and we have considered only a few books in the field. It would not be practical to try to cover every existing work on \devops and condensing it all in this single survey, which is also limited in length. However, by focusing on journal and conference papers, and by applying the snowballing process, we hope to have covered the main literature on the field.
The choice of the main selected studies, primarily in the snowballing process, as well paper classification, may suffer from subjective bias. One contributing factor is that \devops has not a single definition widely accepted by the community. To avoid favoring specific facets of \devops in our selection, we have used only the keyword ``\devops'' in our search query. However, the appearance of the keyword ``\devops'' was not mandatory in the snowballing process, so we could select some important work tackling highly related subjects as, for example, continuous delivery. To reduce the subjective bias, at least two authors participated in the selection process and in the papers classification. More experienced researchers also supervised the whole process.
There is also the publication bias, since positive results are more likely to be published than negative results. We did not find, for example, a paper reporting a case of failed \devops adoption. Therefore, we did not address this issue in this survey.
\section{Conclusions}
\label{sec:conclusions}
In this survey, we have discussed the most common \devops challenges presented by the literature. We based our approach on a conceptual analysis grounded in the academic literature and complemented by other sources.
The two fundamental pillars of \devops are 1) human collaboration across departments and 2) automation. In this survey we found that technical issues regarding delivery automation are more consolidated, having only a few minor controversies. On the other hand, how to effectively enable collaboration among departments is not well discussed, as there are only a few tools for tackling this issue.
A technical topic highly related to \devops revealed by our sources was microservice architecture. Some technical conflicting points found in the literature or in the community are: there is no consensus if microservices should be versioned; some practitioners see configuration management tools and containerization as complementary approaches, but others understand them as competitors; rolling back is usually seen as a \devops practice, but some practitioners tend to favor feature toggles as a way to avoid rolling back.
A fundamental topic that ran through all the sections of this survey is about structuring an organization in the \devops context. The options are 1) keeping collaborating departments, 2) building cross-functional teams, and 3) having \devops teams. Each one of these strategies has its challenges, and, by following the current literature, it is not possible to define the best strategy for a given scenario.
Finally, we found few works focusing on the experience of more than a single organization. Similarly, we found very few works using quantitative metrics for assessing \devops adoption. We did not find any articles reporting negative results. These are some aspects to be improved in future research on \devops.
# remove tags latex
cat *.tex > merge.txt
sed -r -i 's/\\?devops/DevOps/g' merge.txt
detex merge.txt > limpo.txt
# remove citações
sed -r -i 's/[a-zA-Z]+[0-9]{4}[a-zA-Z]+//g' limpo.txt
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
\small
\begin{table}[ht]
\centering
\caption{Papers classification}
\label{tab:papers-classification}
\begin{tabular}{l r r} \hline
\itshape{Category} & \itshape{Quantity} & \itshape{Papers} \\
\hline
% KEEP ORDERED
Support & 10 & \citesel{wettinger2015knowledge, wettinger2015environments, woods2016view, basiri2016chaos, magoutis2015social, pang2016maintenance, jaatun2018incident, rahman2018defective, li2018api, zhu2015frequency} \\
Impact & 8 & \citesel{yasar2016security, shahin2016architecting, roche2013quality, jaatun2017security, cerqueira2015researchops, rajkumar2016culture, sill2014standards, rossem2018virtualized} \\
Experience report & 7 & \citesel{balalaie2016microservices, callanan2016right, chen2015huge, feitelson2013facebook, gray2006conversation, neely2013easy, siqueira2018gov} \\
Surveys & 6 & \cite{travassos2016SLR, Erich2017SLR, gill2017SLR, Jabbari2016SLR, Bosch2017SLR, Paasivaara2015LSR} \\
Introduction & 6 & \citesel{humble2011devops, humble2017willwork, punjabi2016stories, bass2018architect, dyck2015release, debois2011revolution} \\
Challenges & 5 & \citesel{laukkarinen2017medical, lwakatare2016towards, diel2016distributed, olsson2012stairway,leppanen2015highways} \\
Education & 3 & \citesel{chung2016ksa, hussain2017zealand, bai2018feedback} \\
Adoption patterns & 3 & \citesel{nybom2016mixing, snyder2018analytics, feijter2018maturity} \\
Tools & 3 & \citesel{ebert2016devops, kang2016docker, kersten2018explosion} \\
Practices and patterns & 2 & \citesel{brown2016microservices, cukier2013patterns} \\
\hline
\end{tabular}
\end{table}
% end small
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment