<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Carlos García</title>
    <description>The latest articles on Forem by Carlos García (@jcharliegarciam).</description>
    <link>https://forem.com/jcharliegarciam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F26980%2Fe2ca5ced-e967-4781-9adb-eb42c45afa43.jpg</url>
      <title>Forem: Carlos García</title>
      <link>https://forem.com/jcharliegarciam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jcharliegarciam"/>
    <language>en</language>
    <item>
      <title>Incrementar seguridad de Dockerfiles quitando privilegios de Root en los contenedores</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Wed, 16 Dec 2020 00:52:37 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/incrementar-seguridad-de-dockerfiles-quitando-privilegios-de-root-en-los-contenedores-13f3</link>
      <guid>https://forem.com/jcharliegarciam/incrementar-seguridad-de-dockerfiles-quitando-privilegios-de-root-en-los-contenedores-13f3</guid>
      <description>&lt;p&gt;Cuidar nuestra seguridad al momento de crear Dockerfiles es igual de importante que todas las demás acciones implementadas para fortalecer la seguridad informática de nuestras aplicaciones.&lt;/p&gt;

&lt;p&gt;Hace un par de días me llamó la atención un artículo sobre seguridad informática enfocado a la configuración y buen uso de la herramienta de Docker. Y aunque no lo había pensado, tiene mucho sentido, muchas veces nos dejamos llevar por los ejemplos que encontramos en línea y no nos damos cuenta que están escritos con mucha simpleza por la misma naturaleza del "tutorial", pero meter este código simple a nuestros ambientes productivos resulta ser un peligro porque la mayoría de las veces pasa por alto la atención al detalle que deberíamos de tener para poder evitar código vulnerable.&lt;/p&gt;

&lt;p&gt;Los ejemplos de la siguiente guía están pensados para proyectos de Net Core pero son perfectamente trasladables a cualquier otro tipo de proyecto.&lt;/p&gt;

&lt;h1&gt;
  
  
  Dockerfiles
&lt;/h1&gt;

&lt;p&gt;Haciendo un poco de investigación al respecto de cómo disminuir el tamaño de las imágenes que utilizo en mis proyectos de Go, me encontré con varias páginas hablando al respecto de las buenas prácticas que debemos de tener al momento de escribir nuestros Dockerfiles.&lt;/p&gt;

&lt;p&gt;Dentro de las practicas mencionaban asignar la menor cantidad de privilegios posibles a nuestros contenedores Docker. Resulta que, por defecto, al momento de ejecutar un proceso dentro de un contenedor, Docker ejecuta dicho proceso con el usuario root. ¿Cómo? Sí, Docker le asigna los permisos de root a todos los procesos que corran dentro de un contenedor.&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker y el Kernel
&lt;/h1&gt;

&lt;p&gt;Antes de continuar, debemos de refrescar un concepto básico de Docker: Docker gana rendimiento porque no es una máquina virtual, simplemente es una herramienta para correr procesos específicos dentro de contenedores y, así poder tener un mejor manejo de dependencias y asegurarnos de que lo que funciona en nuestro sistema local, también funcionará en nuestro servidor. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estos contenedores comparten el Kernel con la máquina Host.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Debido a que el Kernel es el encargado de la administración de los uid y gid (User Id y Group Id) los usuarios dentro de los contenedores tendrán los mismos privilegios afuera de los mismos. Un proceso ejecutado por root dentro de un contenedor Docker hereda los mismos privilegios que un usuario root en el Host.&lt;/p&gt;

&lt;p&gt;Esto es peligroso porque expone la información confidencial que tengamos en nuestra máquina virtual en la nube (o peor, nuestro servidor on-premise) y abre la puerta a que cualquier atacante puedan escalar a privilegios root después de haber ganado acceso a cualquier contenedor con privilegios de root. ¿Se acuerdan de la historia de terror de David Gilberson? (&lt;a href="https://medium.com/hackernoon/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5"&gt;https://medium.com/hackernoon/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5&lt;/a&gt;) ¿Qué pasaría si incluyéramos una dependencia así en alguno de nuestros contenedores con privilegios de root?&lt;/p&gt;

&lt;h1&gt;
  
  
  La prueba
&lt;/h1&gt;

&lt;p&gt;Si ustedes crean un contenedor (de una imagen de desarrollo en la que se use directamente el usuario root) tienen varias formas de comprobar cuales privilegios son los que tiene el proceso corriendo en el contenedor.&lt;/p&gt;

&lt;p&gt;Lo primero que pueden hacer es entrar a la consola interactiva y preguntar por el usuario actual. Podemos hacer esto con el comando &lt;em&gt;whoami&lt;/em&gt; o el comando &lt;em&gt;id -u,&lt;/em&gt; la salida debería ser la siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;idContenedor&amp;gt; /bin/bash
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;whoami
&lt;/span&gt;root
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;
0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;También podemos ver los procesos que se están ejecutando en un contenedor en específico sin tener que entrar a la consola interactiva:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker top &amp;lt;idContenedor&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La salida del comando anterior nos dará el id del proceso que se está ejecutando dentro del contenedor así como el nombre del usuario que lo ejecutó.&lt;/p&gt;

&lt;p&gt;Nota: en los enlaces que puse al final del texto se usan comandos como ps, pero al intentar usarlos en la consola interactiva de la imagen de .Net nos damos cuenta que el comando no está disponible.&lt;/p&gt;

&lt;h1&gt;
  
  
  La solución
&lt;/h1&gt;

&lt;p&gt;La solución inmediata para remediar este problema es crear un usuario y asignarlo al contenedor al momento de crearlo, esto siendo en el Dockerfile. Las siguientes lineas nos ayudaran a hacerlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;groupadd &lt;span class="nt"&gt;-r&lt;/span&gt; nombreGrupo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; nombreGrupo nombreUsuario
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; nombreUsuario&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los comandos para crear usuarios y grupos son distintos entre las diferentes distribuciones Linux que usemos como base en nuestro Dockerfile.&lt;/p&gt;

&lt;p&gt;Agregando estas dos lineas en el stage final del Dockerfile, antes de ejecutar el ENTRYPOINT, nos permitirá usar este usuario en vez de root.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kestrel y aplicaciones Non Root
&lt;/h2&gt;

&lt;p&gt;Después de hacer estos cambios e intentar correr el proyecto, nos daremos cuenta el proyecto no va a poder arrancar.&lt;/p&gt;

&lt;p&gt;El problema aquí es que aun que el puerto por default que usa Kestrel para servir nuestra api durante el desarrollo es el 5000, al momento que incluimos la imagen &lt;a href="http://mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim"&gt;mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim&lt;/a&gt; (runtime de net core) de base en nuestro Dockerfile, seteamos inconscientemente el puerto 80 como el designado para nuestra aplicación.&lt;/p&gt;

&lt;p&gt;Lo único que necesitamos hacer para remediar lo anterior es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ASPNETCORE_URLS=http://+:5000&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Justo después de hacerle pull a la imagen de runtime que usamos para nuestro proyecto de Net Core.&lt;/p&gt;

&lt;p&gt;Lo único que queda por hacer, sería routear el puerto 8080 del host con el 5000 del container, esto dentro del docker-compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.7'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;
        &lt;span class="s"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:5000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  La lección
&lt;/h1&gt;

&lt;p&gt;Así como revisamos la precedencia de las dependencias que usamos en nuestros proyectos, también debemos de informarnos acerca de las imágenes que usamos como base para nuestros proyectos ya que no todas están preparadas para subirse a producción. Es por lo anterior que siempre tenemos que revisar qué es lo que hacen estas imágenes base y hacer nuestro Dockerfile multistage para poder definir bien la imagen que correrá en nuestro ambiente productivo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enlaces de referencia
&lt;/h1&gt;




&lt;p&gt;&lt;a href="https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15"&gt;Running a Docker container as a non-root user&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user"&gt;Best practices for writing Dockerfiles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#endpoint-configuration"&gt;Kestrel web server implementation in ASP.NET Core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b"&gt;Processes In Containers Should Not Run As Root&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/jobteaser-dev-team/docker-user-best-practices-a8d2ca5205f4"&gt;Docker user best practices&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/better-programming/running-a-container-with-a-non-root-user-e35830d1f42a"&gt;Docker Tips: Running a Container With a Non Root User&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf"&gt;Understanding how uid and gid work in Docker containers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>netcore</category>
    </item>
    <item>
      <title>I am a Mexican Software Developer &amp; Senior CS student, Ask Me Anything!</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Wed, 13 Mar 2019 22:14:25 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/i-thing-about-you-or-thing-you-are-ask-me-anything-210m</link>
      <guid>https://forem.com/jcharliegarciam/i-thing-about-you-or-thing-you-are-ask-me-anything-210m</guid>
      <description>&lt;p&gt;I will be completing my Bachelors Degree in Computer Science in June (in Mex) and I am currently working and doing social service as a Software Developer.&lt;/p&gt;

&lt;p&gt;I thought that maybe it would be interesting for you to know how is it to be a Dev/Student in Latam, so here I am.&lt;/p&gt;

&lt;p&gt;I used to do web development in my work but now I am doing a lot of Image Processing stuff. In the social service (for the University) I am doing Machine Learning in my University's Hospital.  &lt;/p&gt;

</description>
      <category>ama</category>
    </item>
    <item>
      <title>Learning how to learn: CS Edition</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Tue, 09 Oct 2018 19:57:53 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/learning-how-to-learn-cs-edition-1acc</link>
      <guid>https://forem.com/jcharliegarciam/learning-how-to-learn-cs-edition-1acc</guid>
      <description>&lt;p&gt;I never thought I would be a Software Engineer, back when I was little I used to have the firm conviction to be an Architect, but something happened... I realized that the more I grew up the more I became more interested in Computers. After my third semester of High School (I live in México, and in my state, public High School lasts 4 semesters) I came with an answer: I was decided to do a BS in Computer Science.&lt;/p&gt;

&lt;p&gt;Lets go forward 4 months after I started university. It was the end of my first semester in school (2015, 3 years ago), just 4 months of experience coding, my first programming class was object oriented programming and the deadline of my first final project in my CS degree was 1 week away.&lt;/p&gt;

&lt;h4&gt;
  
  
  An ERP system to manage the students, professors, classes and schedules of a university using a MySql Database.
&lt;/h4&gt;

&lt;p&gt;I wanted to cry. Like, literally. It was my first project in my CS career and I was stuck. What is a database? What is SQL? What is a non-relational database? What is a database management system? How can I connect my Java code to a database? I used to have a lot of questions like those, I had no experience and I had no idea in how to do those things.&lt;/p&gt;

&lt;p&gt;Of course that I could have just copied code from stack overflow or pages like that, but I NEEDED to know how things work. For me, copying is just not enough. I was trying to finish the project, doing all from scratch and by my own.&lt;/p&gt;

&lt;p&gt;I remember those nights of searching online in a lot of videos, web pages, books, everything... just to bring to my head new questions. I was totally lost. Searching the web was just doing harm to myself, Computer Science is an ocean of information and I was in the middle of that ocean with no clue of where I was, what to do or what information to search.&lt;/p&gt;

&lt;p&gt;Our team finished the project with help of other students from higher semesters. &lt;/p&gt;

&lt;p&gt;I still remember the feeling. The sensation that you know nothing, that even if you put all your effort in searching information, you don't understand anything, everything seems to be written in a foreign language (Actually it was, everything was in English, but you understand the point).&lt;/p&gt;

&lt;p&gt;Even 6 months later, after a C programming class, searching how to do web programming was like... wait what the hell is a framework and why do people recommend tons of them? What is Django? Backend? Frontend? What is the difference between a framework and a library? Maybe I was too slow, but that was a lot of information for me.&lt;/p&gt;

&lt;p&gt;So I don't know if it was just me or everyone feels this way at the beginning, but I was very lost, I had the wish to learn more, but trying that just left me with more questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I still feel the same?
&lt;/h2&gt;

&lt;p&gt;No. Absolutely no. I think that at some point of my degree I learned how to learn. This is a very import skill, because as a Software Engineer, you need to be updated with new technologies and you need to have the ability to learn new tech and tools as you walk through your career.&lt;/p&gt;

&lt;p&gt;Maybe, eventually, everyone gets to this point. The point where you can surely read any documentation online and pick a new language. The point where you can read about new tech without being completely lost. The point where you can learn whatever you want online, just with a little patience.&lt;/p&gt;

&lt;p&gt;But maybe not, maybe some people gets so frustrated that decides to quit CS, maybe some people will convince themselves thinking: "This is not for me". If you are getting to that point of frustration let me tell you something, you are not alone, everyone in the developers community is here to help you. &lt;/p&gt;

&lt;h4&gt;
  
  
  Do Not Give Up.
&lt;/h4&gt;

&lt;p&gt;The next tips are for you. I want to give you some of my little experience as a CS Student in how to start diving in this beautiful ocean of knowledge. Keep in mind that this tips were the little things that helped me out to be a better learner, this tips may not be useful for your situation because we are all different.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Ask for help
&lt;/h2&gt;

&lt;p&gt;Maybe it sounds obvious, but it is not. Sometimes our pride doesn't let us to ask for help, even tho it is a normal and healthy thing to do. &lt;/p&gt;

&lt;p&gt;Don't expect someone giving you all the answers. Ask for advice, ask for experiences, try to understand how they learned what they know, try to figure out what do you need to start to study to get to the level where they are. Ask for advice to know how you will start tackling all the information that is out there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be Social
&lt;/h2&gt;

&lt;p&gt;Going to Campus Party México (A tech convention full of conferences) has been one of the best experiences of my life. I spent 8 hours traveling in a bus with a bunch of strangers across the country just to meet new people and to learn all that I could about technology.&lt;/p&gt;

&lt;p&gt;Talking to all the devs, the hackers, the creative people and even the business people, all of that helped me to grow in an incredible way.&lt;/p&gt;

&lt;p&gt;Having conversations with people that have more experience than you is like reading a good book. It's amazing. You get to know experiences that will help you through you journey, knowing what is going to come and how they affronted those situations is a great opportunity for you to think about how you could react to similar situations. You start to discover a lot of things that you were unaware of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Math is fun
&lt;/h2&gt;

&lt;p&gt;Not everybody thinks this way but I do.&lt;/p&gt;

&lt;p&gt;Having a good background in math is very helpful for every programmer. Probably in you daily work you will not use derivatives and integrals BUT algebra, calculus, probability and geometry will give you an excellent sense of logic.&lt;/p&gt;

&lt;p&gt;I am not saying that you have to be good at math to be a good dev. My point is that, in my case, I can see a relation between having more ability with math and having more understanding in how a computer works and more ease writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read Read and Read
&lt;/h2&gt;

&lt;p&gt;Reading is fundamental for your development. Articles like the ones that you can find here or in any development site are very helpful.&lt;/p&gt;

&lt;p&gt;Be a proactive student, don't be satisfied with the information that you get in the school, in the bootcamp or in the online-course. &lt;/p&gt;

&lt;p&gt;You need to be hungry of information. Time is not an excuse, I read "Clean Code" by Robert C. Martin between my Uni classes even tho I work halftime as a Web Dev. &lt;/p&gt;

&lt;h4&gt;
  
  
  If I can do it, you surely can.
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Make CS an important part of your life
&lt;/h2&gt;

&lt;p&gt;After a few months into my degree I realized that making CS a constant topic in my life, and I am not including here my "Academic Life", was a great way to learn about short topics in a fun and fast way.&lt;/p&gt;

&lt;p&gt;When I say "Make CS an important part of my life" I am referring to little things like, following YouTube channels about CS, following devs in Twitter, going to conferences about tech, making CS a topic of conversation with other devs/classmates instead of talking about the last-night episode of -insert favorite show- and even talking with my Uni professors about their experience in the tech industry.&lt;/p&gt;

&lt;p&gt;I am not saying that you should leave all your hobbies to live a 100% software engineering life. I am saying that you should consider CS as another hobbie in your life.&lt;/p&gt;

&lt;p&gt;It's okey if this is too much CS for you, some people prefer to think about this things only in their work time. But, if you are like me and you absolutely LOVE coding and learning new things about tech everyday, you should consider this advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not stress out
&lt;/h2&gt;

&lt;p&gt;This point is very important. Always keep calm.&lt;/p&gt;

&lt;p&gt;NO ONE knows everything, so keep calm. It is okey if you don't understand some topic, it is okey if you don't understand some tech and it is okey if you just don't 'feel' to learn it.&lt;/p&gt;

&lt;p&gt;I used to stress out a lot because my skills in web development (specially front-end) are not the best out there, but after some time thinking about what I really want in my life I realized that web development Its just not my thing. &lt;/p&gt;

&lt;p&gt;So, after all, there was no point in getting stressed because I didn't know the latest JavaScript framework or because I didn't know how to do good front end design if at the end of the day I was going to pursue the low level programming and algorithms path.&lt;/p&gt;




&lt;p&gt;Those were some aspects of my life as student that helped me to learn more and faster. Maybe those points do not apply for you, but I feel the need to bring new ideas to the discussion, because after all, communities like this one helped me in my introduction to this industry.&lt;/p&gt;

&lt;p&gt;Sometimes you can feel down, sometimes you can feel that your productivity levels are really low and that you are not learning anything, but let me say to you this: Eventually, everything gets better, just keep going, keep learning, keep putting effort in what you want.&lt;/p&gt;

&lt;p&gt;"Everything in this life has a fix, except death" So enjoy your life learning what you love.&lt;/p&gt;

&lt;p&gt;Thank you for reading ~&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Understanding: Program Stack and Recursion</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Thu, 27 Sep 2018 06:03:01 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/understanding-program-stack--recursion-2ii</link>
      <guid>https://forem.com/jcharliegarciam/understanding-program-stack--recursion-2ii</guid>
      <description>&lt;p&gt;Recently, I've been doing a lot of research in "advance topics" of C++, I am very interested in things like memory management and optimization (I'm currently reading "Introduction to Algorithms" to improve my skills). &lt;/p&gt;

&lt;p&gt;In my research, I found the topic of recursion. I studied this topic in my "Data Structures" class in university, but I wanted to understand in a deep way how the computer handles recursion and how it can be used instead loops.&lt;/p&gt;

&lt;p&gt;In this post I will be explaining how I understood the role that the stack plays in recursion and how you can apply recursion in linear algebra to obtain the determinant of a matrix.&lt;/p&gt;

&lt;h2&gt;
  
  
  So... what is the Stack?
&lt;/h2&gt;

&lt;p&gt;The stack is a LIFO data structure (Last in, first out). It is literally what you imagine: when you "push" data, this data will go into the stack and it will sit above the last pushed element converting itself in the new "top" element. This process will repeat each time you "push" data to the stack. &lt;/p&gt;

&lt;p&gt;When you want to read an element from the stack, you "pop" the top element of the stack. That is why the last element pushed into the stack is the first element to get out of the stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fb%2Fb4%2FLifo_stack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fb%2Fb4%2FLifo_stack.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Relation between the Stack and Recursion
&lt;/h2&gt;

&lt;p&gt;Well, when you are running a code (Let's say, a C++ code) the runtime of the language manages the "program-stack" this stack will be the structure used the store the variables used in your code and the calls to the different functions that you invoke in your code.&lt;/p&gt;

&lt;p&gt;(Dynamic memory spaces created with the 'new' operator are stored in the "Heap", which is a different structure than the Program-Stack)&lt;/p&gt;

&lt;p&gt;Keeping track of the function calls with the Stack makes possible things like passing parameters, returning values and of course: Recursion.&lt;/p&gt;

&lt;p&gt;Every time you call a function in your code, the runtime will push a "stack frame" into the stack. The stack frame is a block of information that contains the information of the subrutine. This information includes: the parameters, a return address and the local variables of the function. &lt;/p&gt;

&lt;p&gt;When you use recursion, you are pushing a stack frame each time your function calls itself. The Call Stack (or "Program-Stack" as mentioned before) has a finite size per program run (The size is calculated before the program execution), this can lead to a dangerous situation because you can actually surpass the quantity of information that the stack can hold: this is the famous "Stack-Overflow".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Fd%2Fd3%2FCall_stack_layout.svg%2F342px-Call_stack_layout.svg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Fd%2Fd3%2FCall_stack_layout.svg%2F342px-Call_stack_layout.svg.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Call_stack_layout.svg/342px-Call_stack_layout.svg.png" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But don't hold yourself, the runtime will not be pushing stack frames to the stack all the time. When you use the "Return" argument or when the function terminates its execution, the program will return to the "Return Address" and the stack frame will be pop out of the stack.&lt;/p&gt;

&lt;p&gt;This is why is so important to have a base case for the recursion. The base case is the case in which the function will not call itself but return an specific value to the previous call.&lt;/p&gt;

&lt;p&gt;The base case assure us that at some point of the recursion the functions will start to "roll back" and this will start to pop the stack frames of the recursion out of the Stack.&lt;/p&gt;

&lt;p&gt;If you don't have a base case, you will definitely cause a Stack Overflow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using recursion to get the determinant of a Matrix.
&lt;/h2&gt;

&lt;p&gt;So, in the next part I will try to demonstrate how to use recursion to get the determinant of a matrix. (This code is a first draft, so there is room for improvement, feel free to give suggestions about the code).&lt;/p&gt;

&lt;p&gt;This code will be using the "Standard Method" for solving determinants, if you don't know how it works, you can find how to do it &lt;a href="https://www.khanacademy.org/math/algebra-home/alg-matrices/alg-determinants-and-inverses-of-large-matrices/v/finding-the-determinant-of-a-3x3-matrix-method-2" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now lets see the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//We will pass the matrix and the size n of the matrix(nxn)&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;determinant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="cm"&gt;/*This one is the base case! 
        This case will return the result for the smallest sub-matrix (2x2)*/&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//This bool is used for the additions of determinants of the sub-matrices. &lt;/span&gt;
        &lt;span class="c1"&gt;//Remember that we will add in a pattern of (+ - + - ...)&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isNegativeAddition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;determinantResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;//This is a temporary place to store the values for the new matrix&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;numbersForNewRecursiveCall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;

            &lt;span class="c1"&gt;//We fill the temp with the values of the new sub-matrix&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                        &lt;span class="n"&gt;numbersForNewRecursiveCall&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;sx&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;//Then we fill an Array[][]&lt;/span&gt;
            &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;subMatrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;declareArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;sx&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                    &lt;span class="n"&gt;subMatrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sy&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;sx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbersForNewRecursiveCall&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="cm"&gt;/*This is the important part:
            The if is to determine when we will add or when we will rest 
            the determinants of the sub-matrix
            We will add the value of the previous determinant results with 
            the multiplication of the value that determines the sub-matrix and 
            the determinant of that particular sub-matrix*/&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isNegativeAddition&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="n"&gt;determinantResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;determinantResult&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;determinant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subMatrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;isNegativeAddition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;determinantResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;determinantResult&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;determinant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subMatrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                &lt;span class="n"&gt;isNegativeAddition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;determinantResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see here, the recursion helps us to go to the smallest matrix possible in the method, get its determinant (base case) and then go up all the way to the addition of the different determinants of the n sub-matrices of the biggest (nxn) matrix.&lt;/p&gt;

&lt;p&gt;This is literally my second post trying to give back some knowledge to the community so I will appreciate all the feedback that you guys can give to me. Also, I want to mention that the goal of this was not to code the best method for determinant solving, the goal of this was to explain the Stack and how Recursion works.&lt;/p&gt;

&lt;p&gt;Thank you very much for reading this post ~&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>datastructures</category>
      <category>begginers</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Gauss-Jordan in C++</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Sat, 02 Sep 2017 18:57:14 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/gauss-jordan-in-c</link>
      <guid>https://forem.com/jcharliegarciam/gauss-jordan-in-c</guid>
      <description>&lt;p&gt;So, a few days ago the Numerical Analysis teacher from my university left us with a proyect of coding a mathematical method of solving equations.&lt;/p&gt;

&lt;p&gt;At first I thought of doing just a single solution for the problem, but whats the fun I that? So after thinking in funny ways to do my homework (I'm kinda nerd) I ended up doing the solution in C++ and in CUDA programming. &lt;/p&gt;

&lt;p&gt;Notice that I really don't know how to code in CUDA, but man it's not real work so It's ok to learn from the mistakes. &lt;/p&gt;

&lt;p&gt;This is my first time posting my code, so It would be really nice to read feedback from you guys.&lt;/p&gt;

&lt;p&gt;So, this is my approach of the problem in C++&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void jordan(double** matrix, double **answers, int matrixSize) { //Gauss-Jordan
//clock_t begin = clock();
double temp = 0;
for (int i = 0; i &amp;lt; matrixSize; i++) { //Recorre diagonalmente el arreglo - Goes in a diagonal way throught the matrix
    temp = matrix[i][i];
    for (int x = 0; x &amp;lt; matrixSize; x++) { //Hace 1 la diagonal ([i][i]) y divide al resto de la fila - Makes 1 the number in [i][i] and divides the row 
        matrix[i][x] = matrix[i][x] / temp;
    }
    answers[i][0] = answers[i][0] / temp;
    double multiplyFactor = 0;
    for (int y = 0; y &amp;lt; matrixSize; y++) {
        if (y != i) {
            multiplyFactor = matrix[y][i];
            for (int x = i; x &amp;lt; matrixSize; x++) { //Recorre la fila haciendo 0 las coordenadas en la columna de [i][i] - Makes 0 the numbers in the column of [i][i]
                matrix[y][x] = matrix[y][x] - (matrix[i][x] * multiplyFactor);
            }
            answers[y][0] = answers[y][0] - (answers[i][0] * multiplyFactor);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And this is in CUDA&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__global__ void jordanGPU(long double ** matrix, long double * answer, int i)
{
    int idx = threadIdx.x;
    if (idx != i) {
            double multiplyFactor = matrix[idx][i];
            for (int x = i; x &amp;lt; 350; x++) { //Recorre la fila haciendo                     0 las coordenadas en la columna de [i][i]
            matrix[idx][x] = matrix[idx][x] - (matrix[i][x] *         multiplyFactor);
        }
    answer[idx] = answer[idx] - (answer[i] * multiplyFactor);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;clock_t begin = clock();
    double temp = 0;
    for (int i = 0; i &amp;lt; matrixSize; i++) { //Recorre diagonalmente el arreglo
        temp = matrix[i][i];
        for (int x = 0; x &amp;lt; matrixSize; x++) { //Hace 0 la diagonal ([i][i]) y divide al resto de la fila
            matrix[i][x] = matrix[i][x] / temp;
        }
        answers[i] = answers[i] / temp;

        cudaMemcpy(matrixGPU, matrix, matrixBytes, cudaMemcpyHostToDevice);
        cudaMemcpy(answersGPU, answers, answerBytes, cudaMemcpyHostToDevice);

        jordanGPU &amp;lt;&amp;lt; &amp;lt;1, 350 &amp;gt;&amp;gt; &amp;gt;(matrixGPU, answersGPU, i);

        cudaMemcpy(matrix, matrixGPU, matrixBytes, cudaMemcpyDeviceToHost);
        cudaMemcpy(answers, answersGPU, answerBytes, cudaMemcpyDeviceToHost);

        cudaFree(matrixGPU);
        cudaFree(answersGPU);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Hope to read recommendations and suggestions about my code from you guys!&lt;br&gt;
Thanks for reading!~&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Forming a programming career</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Fri, 18 Aug 2017 18:53:34 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/forming-a-programming-career</link>
      <guid>https://forem.com/jcharliegarciam/forming-a-programming-career</guid>
      <description>&lt;p&gt;Being a computer science student is kinda hard, not because the classes, but because I'm completely lost in what I want to do with my professional live after university. And when I say lost... I REALLY mean it.&lt;/p&gt;

&lt;p&gt;I am currently working in web. We are asked to do both front and back end. We use JavaScript, C# WebServices and SqlServer. I just love doing C# and SQL, but I really hate the JavaScript/jQuery/Angular/CSS/HTML part which is like the 70% of work that I have.&lt;/p&gt;

&lt;p&gt;I am afraid of getting stuck in this situation. I really like programming in C, C++, Java, C++, Sql, doing Arduino proyects, learning about algorithms, AI and I currently signed up for an Assembly class in the University. I just cant imagine my future doing web programming.&lt;/p&gt;

&lt;p&gt;I just don't know where to start to start doing what I like. What type of career should I start forming?&lt;/p&gt;

&lt;p&gt;I would love to read personal experiences from you guys. Thanks for reading.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Recomendations in choosing a Linux distro</title>
      <dc:creator>Carlos García</dc:creator>
      <pubDate>Thu, 03 Aug 2017 03:04:05 +0000</pubDate>
      <link>https://forem.com/jcharliegarciam/recomendations-in-choosing-a-linux-distro</link>
      <guid>https://forem.com/jcharliegarciam/recomendations-in-choosing-a-linux-distro</guid>
      <description>&lt;p&gt;So, last semester I took a class about Bioinformatics (Python Programming) and the professor made us to use Fedora, we really didn't learn like a lot of Linux, just the basics.&lt;/p&gt;

&lt;p&gt;Since I'm studying computer science I think that learning Linux (In a more complete way) will be very usefull for my career. So, with your experience, which distro do you recommend me to get started? (I will be very gratefull if you recommend a book or a online course to learn about it).&lt;/p&gt;

&lt;p&gt;Thank you for your time guys, and sorry for my english, greetings from Mexico!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
