<?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>DEV Community: Hein Khant Zaw</title>
    <description>The latest articles on DEV Community by Hein Khant Zaw (@heinkhantzaw).</description>
    <link>https://dev.to/heinkhantzaw</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%2F485622%2F0a9e1809-839d-4978-992b-e7055d16bb7e.png</url>
      <title>DEV Community: Hein Khant Zaw</title>
      <link>https://dev.to/heinkhantzaw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heinkhantzaw"/>
    <language>en</language>
    <item>
      <title>Django Deployment with Nginx in Ubuntu</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sat, 25 Jun 2022 08:03:51 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/django-deployment-with-nginx-in-ubuntu-1cin</link>
      <guid>https://dev.to/heinkhantzaw/django-deployment-with-nginx-in-ubuntu-1cin</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This was just a note for myself as I faced several errors during my first deployment with Django. This note is for those who are facing problems during the deployment. I hope it helps!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install the Packages from the Ubuntu Repositories first. If you are using Django with Python 3, type:&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="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;python3-pip python3-dev libpq-dev nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Postgresql installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MySQL installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;mysql-server
mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Database creation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;myproject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; Postgres
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="n"&gt;myprojectuser&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;myproject&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;myprojectuser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; MySQL
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'newuser'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'newuser'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python VirtualEnv Creation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; pip3 &lt;span class="nb"&gt;install &lt;/span&gt;virtualenv
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/myproject
virtualenv myprojectenv
&lt;span class="nb"&gt;source &lt;/span&gt;myprojectenv/bin/activate 
pip &lt;span class="nb"&gt;install &lt;/span&gt;django gunicorn psycopg2 &lt;span class="o"&gt;(&lt;/span&gt;For Postgres&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Changes in setting.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.postgresql_psycopg2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myproject&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myprojectuser&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&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="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.mysql&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myproject&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myprojectuser&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Migrations
&lt;/h3&gt;

&lt;p&gt;Now, we can migrate the initial database schema to our database using the management script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py makemigrations
python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an administrative user for the project by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will have to select a username, provide an email address, and choose and confirm a password.&lt;br&gt;
We can collect all of the static content into the directory location we configured by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py collectstatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a Gunicorn systemd Service File
&lt;/h2&gt;

&lt;p&gt;Now, we are going to implement a more robust way of starting and stopping the application server with Gunicorn. To accomplish this, we’ll make a systemd service file.&lt;/p&gt;

&lt;p&gt;Create and open a systemd service file for Gunicorn with sudo privileges in your text editor:&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="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/system/gunicorn.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  gunicorn.service file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gunicorn daemon
&lt;span class="nv"&gt;Requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gunicorn.socket
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify
&lt;span class="c"&gt;# the specific user that our service will run as&lt;/span&gt;
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root
&lt;span class="nv"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root
&lt;span class="c"&gt;# another option for an even more restricted service is&lt;/span&gt;
&lt;span class="c"&gt;# DynamicUser=yes&lt;/span&gt;
&lt;span class="c"&gt;# see http://0pointer.net/blog/dynamic-users-with-systemd.html&lt;/span&gt;
&lt;span class="nv"&gt;RuntimeDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gunicorn
&lt;span class="nv"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/www/html/[ProjectName]
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/www/html/[ProjectName]/project_venv/bin/gunicorn config.wsgi
&lt;span class="nv"&gt;ExecReload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/bin/kill &lt;span class="nt"&gt;-s&lt;/span&gt; HUP &lt;span class="nv"&gt;$MAINPID&lt;/span&gt;
&lt;span class="nv"&gt;KillMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mixed
&lt;span class="nv"&gt;TimeoutStopSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&lt;span class="nv"&gt;PrivateTmp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check for the Gunicorn Socket File
&lt;/h3&gt;

&lt;p&gt;Check the status of the process to find out whether it was able to start:&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="nb"&gt;sudo &lt;/span&gt;systemctl status gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create gunicorn.socket
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/system/gunicorn.socket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  gunicorn.socket File
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gunicorn socket

&lt;span class="o"&gt;[&lt;/span&gt;Socket]
&lt;span class="nv"&gt;ListenStream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/run/gunicorn.sock
&lt;span class="c"&gt;# Our service won't need permissions for the socket, since it&lt;/span&gt;
&lt;span class="c"&gt;# inherits the file descriptor by socket activation&lt;/span&gt;
&lt;span class="c"&gt;# only the nginx daemon will need access to the socket&lt;/span&gt;
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;www-data
&lt;span class="c"&gt;# Optionally restrict the socket permissions even more.&lt;/span&gt;
&lt;span class="c"&gt;# Mode=600&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sockets.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run gunicorn service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start gunicorn
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;gunicorn
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status gunicorn
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure Nginx to Proxy Pass to Gunicorn
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/nginx/sites-available/[ProjectName]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;upstream app_server &lt;span class="o"&gt;{&lt;/span&gt;
    server unix:/run/gunicorn.sock &lt;span class="nv"&gt;fail_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

server &lt;span class="o"&gt;{&lt;/span&gt;
    listen 80&lt;span class="p"&gt;;&lt;/span&gt;
    listen &lt;span class="o"&gt;[&lt;/span&gt;::]:80&lt;span class="p"&gt;;&lt;/span&gt;
    server_name 128.199.221.253&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;# here can also be the IP address of the server&lt;/span&gt;

    keepalive_timeout 5&lt;span class="p"&gt;;&lt;/span&gt;
    client_max_body_size 4G&lt;span class="p"&gt;;&lt;/span&gt;

    access_log /var/www/html/[ProjectName]/logs/nginx-access.log&lt;span class="p"&gt;;&lt;/span&gt;
    error_log /var/www/html/[ProjectName]/logs/nginx-error.log&lt;span class="p"&gt;;&lt;/span&gt;

    location /static/ &lt;span class="o"&gt;{&lt;/span&gt;
        autoindex on&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;alias&lt;/span&gt; /var/www/html/[ProjectName]/static/&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;# checks for static file, if not found proxy to app&lt;/span&gt;
    location / &lt;span class="o"&gt;{&lt;/span&gt;
        try_files &lt;span class="nv"&gt;$uri&lt;/span&gt; @proxy_to_app&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;

    location @proxy_to_app &lt;span class="o"&gt;{&lt;/span&gt;
      proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      proxy_set_header Host &lt;span class="nv"&gt;$http_host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      proxy_redirect off&lt;span class="p"&gt;;&lt;/span&gt;
      proxy_pass http://app_server&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding SSL Certificate
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream app_server {
    server unix:/run/gunicorn.sock fail_timeout=0;
}

server {
    listen 80;
    listen [::]:80;
    server_name 128.199.79.246;  # here can also be the IP address of the server
    return 301 https://[DomainName]$request_uri;
  }

server{
    # SSL configuration
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name [DomainName];

    ssl        on;
    ssl_certificate         /etc/ssl/certs/cert.pem;
    ssl_certificate_key     /etc/ssl/private/key.pem;
    ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
    ssl_verify_client on;

    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/[UserName]/logs/nginx-access.log;
    error_log /home/[UserName]/logs/nginx-error.log;

    location /static/ {
        autoindex on;
        alias /home/[UserName]/[ProjectName]/[DjangoAppName]/static/;
    }

    # checks for static file, if not found proxy to app
    location / {
        try_files $uri @proxy_to_app;
      }

    location @proxy_to_app {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://app_server;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Restart all the service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart gunicorn
&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>django</category>
      <category>nginx</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Parameter Passing</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sat, 25 Jun 2022 07:46:12 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/parameter-passing-5527</link>
      <guid>https://dev.to/heinkhantzaw/parameter-passing-5527</guid>
      <description>&lt;p&gt;Parameters ဆိုတာက subprogram (subprogram ဆိုတာက C++ မှာဆို function, Java မှာဆို Methods) ထဲမှာ သုံးဖို့အတွက်‌ထည့်ပေးလိုက်တဲ့ တန်ဖိုး(or) subprogram ကနေတွက်ထုတ်‌ေပးလိုက်တဲ့တန်ဖိုး ကိုခေါ်တယ်။&lt;/p&gt;

&lt;p&gt;Formal parameter ဆိုတာက subprogram ထဲမှာပါတဲ့ parameter ကိုပြောတာ&lt;br&gt;
Actual parameter ဆိုတာက subprogram ကိုခေါ်တဲ့အချိန် မှာထည့်ပေးလိုက်တဲ့ဟာကိုခေါ်တယ်။ Actual parameter ကို Arguments လို့လဲေခါ်ကြပါတယ်။&lt;/p&gt;
&lt;h4&gt;
  
  
  Example of formal parameters
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;addTwoNum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// a and b are formal parameters&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// a, b are input parameters&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// c is output parameter&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Example of actual parameters (a.k.a Arguments)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;addTwoNum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//num1 and num2 are actual parameters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;အဲ့တော့ subprogram တစ်ခုကိုခေါ်မယ်ဆိုရင် ဘယ်လိုဖြစ်သွားသလဲဆိုတော့&lt;br&gt;
actual parameter ထဲကတန်ဖိုးကို formal parameter ထဲလွဲပေးလိုက်တယ်။&lt;br&gt;
subprogram က သူ့ထဲက formal parameter နဲ့ပဲအလုပ်လုပ်တယ်။&lt;br&gt;
အပေါ်က code မှာဆိုရင် num1, num2 ကို &lt;code&gt;addTwoSum()&lt;/code&gt; ထဲထည့်ပေးလိုက်&lt;br&gt;
တာတွေ့တယ်မလား။ အဲ့ num1, num2 ထဲက တန်ဖိုးက &lt;code&gt;addTwoNum()&lt;/code&gt;&lt;br&gt;
ထဲရောက်သွားတော့ a, b အနေနဲ့ပဲ calculation လုပ်သွားတယ်။ &lt;br&gt;
ဒီလောက်ဆို formal နဲ့ actual ကိုကွဲပြီထင်တယ်။&lt;/p&gt;
&lt;h2&gt;
  
  
  Input, Output, Input/Output
&lt;/h2&gt;

&lt;p&gt;Input parameter က subprogram ကလက်ခံတဲ့ parameter ကိုခေါ်တာ။&lt;br&gt;
အပေါ်က formal parameters example မှာပြထားတဲ့ a နဲ့ b ဆိုတာက input parameter ပဲ ။ &lt;/p&gt;

&lt;p&gt;Output parameter ကျတော့ subprogram ကနေ ပြန်ထုတ်ပေးလိုက်တဲ့ parameter ကိုခေါ်တာ။ &lt;br&gt;
Eg. အပေါ်က &lt;code&gt;addTwoNum()&lt;/code&gt; မှာဆိုရင် c က output parameter ဖြစ်တယ်။&lt;/p&gt;

&lt;p&gt;Input/Output parameters ကတော့ subprogram ကလက်ခံထားတဲ့ input parameter ကိုပဲ output parameter အဖြစ် ပြန်ထုတ်ပေးတာကို Input/Output parameter လို့ခေါ်တယ်။&lt;br&gt;
ဆိုလိုချင်တာက input ကိုပဲတန်ဖိုးပြောင်းပြီး ပြန်ထုတ်ပေးလိုက်တာမျိုးကိုပြောတာ။&lt;/p&gt;

&lt;p&gt;input/output parameters က callByReference မှာ‌‌သုံးလို့ရတယ်။&lt;/p&gt;
&lt;h4&gt;
  
  
  Example of input/output parameters
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;addTwoNum&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;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&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;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&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;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// a is input/output parameter&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Value or Reference?
&lt;/h2&gt;

&lt;p&gt;Parameter pass တဲ့အခါမှာ အသုံးအများဆံုးက value pass တာနဲ့ reference ကို pass တာဆိုပြီး နှစ်မျိုးရှိတယ်။&lt;/p&gt;
&lt;h2&gt;
  
  
  Call by Value
&lt;/h2&gt;

&lt;p&gt;Call by Value ဆိုတာက subprogram ထဲကို parameter pass&lt;br&gt;
ပေးတဲ့အခါ ဟိုအပေါ်မှာ‌ေြပာထားသလိုပဲ actual parameter ရဲ့ တန်ဖိုးကို formal parameter ထဲ လွှဲပေးလိုက်တာ။&lt;br&gt;
အဲ့တော့ subprogram ထဲမှာလုပ်သမျှတွေသည် actual parameter ကို ဘာမှလာမပြောင်းလဲစေဘူး။&lt;br&gt;
formal parameter ကပဲပြောင်းသွားလိမ့်မယ်။&lt;/p&gt;
&lt;h3&gt;
  
  
  Example of Call by Value
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;increaseByValue&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;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// n = 2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&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;num&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;increaseByValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This won't change the value in num&lt;/span&gt;
  &lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"After Passing by value :"&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// num = 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Since it's call by value, you'll need to return the value or else, there won't be any effect. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;ဒီ code ထဲမှာဆိုရင် &lt;code&gt;increaseByValue()&lt;/code&gt; က n တန်ဖိုးကို 1 တိုးပေးတယ်။&lt;br&gt;
subprogram တွေက သူတို့အလုပ်ပြီးသွားတာနဲ့&lt;br&gt;
formal parameter ကို destroy လုပ်လိုက်တယ်။&lt;br&gt;
eg. variable n ရဲ့ scope က &lt;code&gt;increaseByValue()&lt;/code&gt; အတွင်းမှာပဲရှိတယ်&lt;br&gt;
အဲ့တော့ သူ့ထဲကတန်ဖိုးက &lt;code&gt;increaseByValue()&lt;/code&gt; ရဲ့အလုပ်ပြီးရင် အပြင်က main function ကိုရောက် မသွားဘူး။&lt;br&gt;
Main function ထဲကိုရောက်ချင်ရင် အဲ့ n ကို output parameter အဖြစ် return ပေးမှပဲရလိမ့်မယ်။&lt;br&gt;
example code မှာက function return ကို void ထားတော့ဘာမှ return မလုပ်ဘူး။&lt;br&gt;
အဲ့တော့ ဘယ်လိုဖြစ်သွားလဲဆိုတော့ &lt;code&gt;increaseByValue(num)&lt;/code&gt; &lt;br&gt;
လုပ်လိုက်တဲ့အခါ n တန်ဖိုးက ၂ တော့ဖြစ်သွားတယ်။ &lt;br&gt;
ဒါပေမယ့် num ရဲ့တန်ဖိုးက ၁ က ၁ ပဲ။ မပြောင်းသွားဘူး။&lt;br&gt;
တကယ်လို့ num မှာပါလာပြောင်းချင်တယ်ဆိုရင် &lt;br&gt;
&lt;code&gt;increaseByValue()&lt;/code&gt; မှာ n ကို return ပေးမှရမယ်။&lt;/p&gt;

&lt;p&gt;I'll show the correct way in this example.&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="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;increaseByValue&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;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// n = 2&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&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;num&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;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;increaseByValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This won't change the value in num&lt;/span&gt;
  &lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"After Passing by value with return statement :"&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// num = 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Since it's call by value, you'll need to return the value or else, there won't be any effect. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Call by reference
&lt;/h2&gt;

&lt;p&gt;Call by Reference ကျတော့ actual parameter ကနေ formal parameter&lt;br&gt;
ထဲတန်ဖိုးလွှဲပေးလိုက်တဲ့အခါမှာ value အစား memory address ကိုလွှဲပေးလိုက်တာ။&lt;br&gt;
Variables ရဲ့ တန်ဖိုးတွေက memory address မှာသိမ်းတာတော့သိတယ်မလား။ အဲ့ address ကိုလွှဲပေးလိုက်တော့ subprogram က အဲ့ variable ကို directly access ရသွားတယ်။ call by value တုန်းကလို တစ်ဆင့်ခံမဟုတ်တော့ဘဲ အဲ့တန်ဖိုးသိမ်းထဲတဲ့နေရာကိုယူပြီး calculationsလုပ်လို့ရသွားတာ။ အဲ့တော့ ဘာကွာလဲဆိုတော့ callByReference မှာဆိုရင် return လုပ်စရာမလိုဘဲ actual parameter ရဲ့ တန်ဖိုးကိုပြောင်းလို့ရသွားလိမ့်မယ်။&lt;/p&gt;

&lt;p&gt;Example ကိုဘာလို့C++နဲ့ရေးလဲဆိုေတာ့....&lt;/p&gt;

&lt;p&gt;Java doesn't support call by reference, so, I wrote it in C++.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example of Call by Value and Call by Reference
&lt;/h3&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/Parameter-passing-example?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Java Enumeration</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sun, 12 Sep 2021 18:45:21 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/java-enumeration-2984</link>
      <guid>https://dev.to/heinkhantzaw/java-enumeration-2984</guid>
      <description>&lt;p&gt;Java SE 5 တွင် Reference Type အသစ်နှစ်မျိုး ဖြည့်စွက်ခဲ့ပါတယ်။ တစ်မျိုးမှာ class ပုံစံ အသစ်တစ်မျိုးဖြစ်တဲ့ enumeration ဖြစ်ပြီး နောက်တစ်မျိုးကတော့ interface ပုံစံအသစ် တစ်မျိုးဖြစ်တဲ့ annotation ဖြစ်ပါသည်။ Enum ဆိုတာကတော့ Enumeration ကိုအတိုကောက်ခေါ်တာဖြစ်ပါတယ်။ Enum type အမျိူးအစားကိုပြောင်းလဲ၍ မရနိုင်သော const တန်ဖိုးများကိုဖော်ပြရန်ဖြစ်ပါတယ်။ လက်တွေ့မှာတော့ Enumerations များအား Constants များအနေနဲ့ အသုံးပြုတဲ့အပြင် singleton pattern များအား ရေးသားတဲ့အခါမှာလည်း အသုံးပြုကြပါတယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/WithoutEnum?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;br&gt;
Java မှာ Enumeration မပါလာခင်တုန်းက Constants တွေအသုံးပြုချင်တယ်ဆိုရင် static final variable များကို အသုံးပြုခဲ့ကြရပါတယ်။ အထက်ပါ code example မှာဆိုရင် Level အတွက် LOW, MEDIUM, HIGH ၏ တန်ဖိုးများကို static final variable များအဖြစ် အသုံးပြုခဲ့ပါတယ်။ အဲ့လိုအသုံးပြုတဲ့အခါ level ၏တန်ဖိုးမှာ int ဖြစ်တဲ့အတွက်ကြောင့် သတ်မှတ်ထားတဲ့ constant တန်ဖိုးများအပြင် အခြားသော int တန်ဖိုးများကိုလည်း အစားထိုး အသုံးပြုလို့ရနေပါတယ်။ &lt;code&gt;System.out.println()&lt;/code&gt; နဲ့ output ထုတ်ပြတဲ့အခါမှာလည်း level အမျိုးအစားကိုထုတ်ပေးမှာမဟုတ်ဘဲ သတ်မှတ်ထားတဲ့ integer ရဲ့တန်ဖိုးကိုသာ ထုတ်ပေးမှာဖြစ်ပါတယ်။

&lt;p&gt;&lt;br&gt;&lt;br&gt;
အထက်ပါ အဆင်မပြေမှုတွေအားလုံးကို Enumeration အသုံးပြု၍ အခုလိုဖြေရှင်းနိုင်ပါလိမ့်မယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/withEnum?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Enums in if Statements
&lt;/h3&gt;

&lt;p&gt;Enum အမျိူးအစားက constants တွေဖြစ်တဲ့အတွက် Program ထဲမှာရှိတဲ့ variables တွေနဲ့ enum constants တွေနဲ့ တိုက်စစ်ရတဲ့ အခြေအနေမျိုးတွေရှိပါတယ်။ &lt;br&gt;
အောက်မှာတော့ Enum ကို if statements တွေထဲမှာ ဘယ်လိုအသုံးပြုလို့ရလဲဆိုတာကို ဖော်ပြထားပါတယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/enumIf?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;Enum ထဲမှာပါတဲ့ constants တန်ဖိုးတွေများရင်တော့ if statements တွေအစား switch statements ကိုအောက်ပါအတိုင်း အသုံးပြုနိုင်ပါတယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Level level = ...  //assign some Level constant to it

switch (level) {
    case HIGH   : ...; break;
    case MEDIUM : ...; break;
    case LOW    : ...; break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Enum Iterations
&lt;/h3&gt;

&lt;p&gt;Enum ထဲက တန်ဖိုးတွေကို Iterations လုပ်ရမယ့် ကိစ္စမျိုးတွေကြုံလာရင်အောက်ပါအတိုင်း ရေးလို့ရပါတယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/enumLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;အထက်ပါ code ထဲမှာပါတဲ့ values() method က Enum type ထဲမှာပါတဲ့ method တစ်ခုဖြစ်ပြီး သူက enum constant တွေပါတဲ့ array တစ်ခုကို return ပြန်ပေးပါတယ်။&lt;br&gt;
အဲ့ array ကိုမှ Enhanced for loop နဲ့ပတ်ပြီး output ထုတ်လိုက်တဲ့အခါ အောက်ပါအတိုင်း ထွက်လာပါလိမ့်မယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HIGH
MEDIUM
LOW
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Enum Methods
&lt;/h3&gt;

&lt;p&gt;Enum ထဲမှာ Methods တွေကိုလည်းထည့်သွင်းရေးသားနိုင်ပါတယ်။ Example အနေနဲ့ Enum ထဲမှာ constructor နဲ့ getter method ဘယ်လိုရေးလို့ရလဲဆိုတာကိုပြောပြပါမယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/enumMethods?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ code ကိုကြည့်မယ်ဆိုရင် main method ထဲမှာ enum level ကို HIGH ပေးထားလိုက်တော့ enum ထဲက constructor က levelCode constant ကို 3 အဖြစ်တန်ဖိုးထည့်ပေးလိုက်ပါတယ်။ နောက် line မှာတော့ &lt;code&gt;getLevelCode()&lt;/code&gt; ဆိုတဲ့ getter method နဲ့ level ရဲ့တန်ဖိုးကိုယူပြီး print ထုတ်လိုက်တော့ output မှာ 3 ထွက်လာမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Enum ထဲတွင် getter/setter methods များသာမက enum constant ၏ field တန်ဖိုးများကို အခြေခံပြီး တခြားသော methods များကိုလည်းဖန်တီးရေးသားနိုင်ပါတယ်။ &lt;/p&gt;

&lt;h3&gt;
  
  
  Enum Abstract Methods
&lt;/h3&gt;

&lt;p&gt;Enum class ထဲမှာ Abstract methods များလည်းရေးသားလို့ရပါတယ်။ တကယ်လို့ ကိုယ်က Enum class ထဲမှာ Abstract method တွေထည့်ရေးထားမယ်ဆိုရင် အဲ့ enum class ထဲမှာပါတဲ့ constant တစ်ခုချင်းစီတိုင်းမှာ abstract method တွေကို  override လုပ်ပေးပြီး ရေးသားပေးဖို့တော့လိုပါလိမ့်မယ်။ ဥပမာ အားဖြင့် အောက်က example ကိုတစ်ချက်ကြည့်ပေးပါ။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/enumAbstract?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;Enum class ရဲ့ အောက်ဆုံးမှာ abstract method ကြေငြာထားတာကိုသတိထားမိကြမယ်ထင်ပါတယ်။ ဒီ example မှာတော့ HIGH, MEDIUM, LOW တစ်ခုချင်းစီအတွက် &lt;code&gt;asLowerCase()&lt;/code&gt; ဆိုတဲ့ abstract method ကို override လုပ်ထားတာကိုတွေ့ရမှာဖြစ်ပါတယ်။ အဆိုပါ abstract method မျိူးကိုဘယ်အချိန်မှာအသုံးပြုသင့်လဲဆိုတော့ Enum class ထဲက constant တွေအတွက် မတူညီတဲ့ methods များရေးရန်လိုအပ်လာတဲ့အခါမှာ အသုံးပြုနိုင်ပါတယ်။&lt;br&gt;
&lt;br&gt;&lt;br&gt;
ဆိုတော့ Enum နဲ့ပတ်သက်တာကတော့ဒီလောက်ပါပဲ။ Java Enum နဲ့ပတ်သက်တဲ့ exercises တွေကို ဒီ &lt;a href="https://javaconceptoftheday.com/java-practice-coding-questions-on-enum-types/"&gt;link&lt;/a&gt; ထဲမှာဝင်လေ့လာလို့ရပါတယ်။&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Java Conditional Statements</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Mon, 05 Jul 2021 07:32:38 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/java-conditional-statements-21ab</link>
      <guid>https://dev.to/heinkhantzaw/java-conditional-statements-21ab</guid>
      <description>&lt;p&gt;Conditional statement ဆိုတာက program အခြေအနေတွေကိုစစ်ဆေးပြီး မှန်ရင်ဘယ်ဟာလုပ် မှားရင်ဘယ်ဟာလုပ် ဆိုပြီး program အသွားအလာကို ထိန်းချုပ်ပေးတဲ့ statement ဖြစ်ပါတယ်။ တနည်းအားဖြင့် အခြေအနေမှန်မမှန် (Boolean တန်ဖိုး true / false) ကို စစ်ဆေးပေးခြင်းဖြစ်ပါတယ်။ Conditional statements တွေကို ဘယ်လိုနေရာမှာသုံးလဲဆိုတော့ နံပါတ်တစ်ခုကို စုံကိန်းလား မကိန်းလား ခွဲတာမျိုးတို့ user ကဘာလုပ်ရင် program မှာဘာဖြစ်မယ်ဆိုတာ မျိုးတို့ မှာ အသုံးပြုပါတယ်။&lt;br&gt;
Conditional statement အမျိုးအစားတွေကတော့ &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;if statement&lt;/li&gt;
&lt;li&gt;switch statement တို့ပဲဖြစ်ပါတယ်။&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  if Statement
&lt;/h3&gt;

&lt;p&gt;if statement ကိုအောက်ပါအတိုင်းထက်ခွဲထားပါတယ် - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if&lt;/li&gt;
&lt;li&gt;if/else&lt;/li&gt;
&lt;li&gt;if/else if/else&lt;/li&gt;
&lt;li&gt;nested if&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ရိုးရိုး if statement ကတော့ if ထဲမှာရှိတဲ့ condition က true ဖြစ်ခဲ့ရင် if block ထဲမှာရှိတဲ့ operation ကိုအလုပ်လုပ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/ifExample?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;အထက်ပါ example မှာဆို age ဆိုတဲ့ integer variable ကို 20 တန်ဖိုးပေးထားပါတယ်။ နောက်တစ်လိုင်းမှာ if condition ကိုမှန်မမှန် အရင်စစ်ပါတယ်။ ပထမ တစ်ခုမှာ မှန်တဲ့အတွက် if block ထဲက &lt;code&gt;System.out.print("Age is greater than 18");&lt;/code&gt; ကိုအလုပ်လုပ်ပါတယ်။&lt;br&gt;
အဲ့တော့ output မှာ Age is greater than 18 ဆိုပြီး ထွက်သွားတာကိုတွေ့ရပါမယ်။&lt;br&gt;
တကယ်လို့ age ကို 18 ထက်ငယ်တဲ့တန်ဖိုးပေးပြီးပြန် run ကြည့်လိုက်ရင် if condition မှားသွားတဲ့အတွက် ဘာမှထွက်လာမှာမဟုတ်ပါဘူး။ &lt;br&gt;
အဲ့တော့ if statement ကို ကိုယ်လိုတဲ့ condition အတိုင်းမှန်ရင် အလုပ်တစ်ခုခုလုပ်စေလိုတဲ့အခါမျိုး မှာအသုံးပြုသင့်ပါတယ်။&lt;/p&gt;
&lt;h4&gt;
  
  
  if/else Statement
&lt;/h4&gt;

&lt;p&gt;if/else statement က if statement နဲ့ပုံစံဆင်တူပါတယ်။ မတူတာကတော့ if statement က မှန်ခဲ့ရင်ဘာအလုပ်လုပ်မလဲဆိုတာကိုပဲညွှန်ကြားနိုင်ပြီး မှားခဲ့ရင် ဘာလုပ်ရမလဲဆိုတာကို ညွှန်ကြားလို့မရပါဘူး။ အဲ့အတွက်ကြောင့် if-else statement မှာဆို condition မှန်ခဲ့ရင် if block ကအလုပ်လုပ်မှာဖြစ်ပြီး condition မှားခဲ့ရင်တော့ else block ကအလုပ်လုပ်မှာဖြစ်ပါတယ်။ &lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed if condition is true&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed if condition is false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/ifelseExample?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;အပေါ်က code example မှာဆိုရင် number variable မှာ 13 လို့တန်ဖိုး သတ်မှတ်ထားပြီး if-else condition မှာ number ကို ၂ နဲ့စားလို့ သုည ကြွင်းရင် စုံကိန်း မဟုတ်ခဲ့ရင် မကိန်းဆိုပြီးတော့ ထုတ်ပေးမှာဖြစ်ပါတယ်။ if ထဲမှာရှိတဲ့ condition က true ဖြစ်ခဲ့ရင် if block ထဲမှာရှိတဲ့ operation ကိုအလုပ်လုပ်ပြီးတော့ false ဖြစ်ခဲ့ရင် else block ထဲမှာရှိတဲ့ operation ကိုအလုပ်လုပ်ပါမယ်။&lt;br&gt;
ဒီ example မှာ number = 13 ဆိုတော့ if ထဲက condition နဲ့မကိုက်တဲ့အတွက် else ထဲက &lt;code&gt;System.out.println("odd number");&lt;/code&gt; ကို အလုပ် လုပ်သွားပါတယ်။&lt;/p&gt;
&lt;h4&gt;
  
  
  if/else if/else Statement
&lt;/h4&gt;

&lt;p&gt;if/else if/else statement ကတော့ ပထမ condition က false ဖြစ်ခဲ့ရင် ဒုတိယ condition ဆီသွားပါတယ် ဒုတိယ condition က true ဖြစ်ခဲ့ရင်တော့ အောက်မှာရှိတဲ့ condition တွေဆီဆက်မသွားတော့ပါဘူး။ တကယ်လို့ ဒုတိယ condition က false ဖြစ်ခဲ့ရင် တတိယ condition ရှိမရှိကြည့်ပြီး ရှိခဲ့ရင်ဆက်စစ်ပါမယ်။ တတိယ condition မရှိခဲ့ရင်တော့ else ရှိမရှိ ကြည့်ပြီး ရှိခဲ့ရင်တော့ else block ထဲက အလုပ်ကိုလုပ်ပါလိမ့်မယ်။ &lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
&lt;span class="c1"&gt;//code to be executed if condition1 is true  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
&lt;span class="c1"&gt;//code to be executed if condition2 is true  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
&lt;span class="c1"&gt;//code to be executed if condition3 is true  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;  
&lt;span class="c1"&gt;//you can add else if as much as you can...  &lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
&lt;span class="c1"&gt;//code to be executed if all the conditions are false  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/ifelseifelseExample?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ program မှာဆိုရင်တော့ int variable mark မှာပေးထားတဲ့တန်ဖိုး အပေါ်မူတည်ပြီး ထုတ်ပေးမှာဖြစ်ပါတယ်။ mark = 65 ဖြစ်တဲ့အတွက် 2nd else if condition နဲ့ကိုက်ညီပြီး အဲ့ block ထဲကအလုပ်ကို လုပ်ဆောင်သွားမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;h4&gt;
  
  
  Nested if Statement
&lt;/h4&gt;

&lt;p&gt;Nested if statement ဆိုတာကတော့ if block ထဲမှာရှိတဲ့ နောက်ထပ် if block တစ်ခုဖြစ်ပါတယ်။ အပြင်ဘက် if ရဲ့ condition က true ဖြစ်မှသာ အတွင်းဘက် if  ရဲ့ condition ဆီကိုရောက်မှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;    
    &lt;span class="c1"&gt;//code to be executed    &lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
        &lt;span class="c1"&gt;//code to be executed    &lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;    
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/nestedIf?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီမှာဆိုရင်တော့ age = 20 နဲ့ weight = 80 ဆိုတဲ့ int variable ၂ ခု ကြေညာထားပြီး ပထမ if condition မှာ age က ၁၈ နဲ့ အထက်ဖြစ်မဖြစ် (age&amp;gt;=18) ကိုစစ်ထားပါတယ်။ မှန်ခဲ့ရင်တော့ ဒုတိယ if condition ထဲမှာ weight က ၅၀ ထက်များမများ (weigh&amp;gt;50) ကို ထပ်စစ် ထားပြီး နှစ်ခုလုံး ကိုက်ညီမှသာ “You are eligible to donate blood” ဆိုတဲ့စာသားကို output ထုတ်ပေးမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;h3&gt;
  
  
  switch statement
&lt;/h3&gt;

&lt;p&gt;Switch statement ဆိုတာကတော့ if/else if/else statement လိုဘဲ condition အများကြီးကို စစ်ဆေးနိုင်ဖို့အတွက်အသုံးပြုပါတယ်။ ဒါပေမယ့်  if/else if/else statement တွေမှာက ကျတော့ condition တွေကို ကိုယ်ကြိုက်သလိုရေးလို့ရပေမယ့် switch statement တွေမှာကတော့ variableရဲ့ value က caseထဲကတန်ဖိုးနဲ့တူမတူစစ်ပြီး operations တွေလုပ်ဆောင်ပေးတာမျိုးဖြစ်ပါတယ်။ switch ထဲမှာ ထည့်စစ်လို့ရတဲ့ data type တွေကတော့ byte, short, char, and int အစရှိတဲ့ primitive data types တွေရယ်၊ Enum နဲ့ String data type တွေထည့်စစ်လို့ရမှာဖြစ်ပြီး case ထဲမှာကတော့ switch ထဲမှာပါတဲ့ datatype အလိုက် value ကိုက်မကိုက်စစ်မယ့် တန်ဖိုးတွေ ရေးပေးရမှာဖြစ်ပါတယ်။ value ကိုက်ညီမယ်ဆိုရင်တော့ ကိုက်တဲ့ case  ထဲကအလုပ်ကိုလုပ်မှာဖြစ်ပါတယ်။ case ထဲကအလုပ်ကိုလုပ်ရင်း break keyword တွေ့ရင်တော့ switch statement ထဲကနေ ထွက်သွားမှာဖြစ်ပြီး break မရှိခဲ့ရင်တော့ အောက်မှာ ကျန်သေးတဲ့ case ထဲကအလုပ်တွေကိုပါ ဆက်လက်လုပ်ဆောင်သွားမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;default ဆိုတာကတော့ case ထဲကvalueတွေလုံးဝမတူညီတဲ့အချိန်မှာလုပ်ရမယ့် အလုပ်တွေကို ရေးရမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;    
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;value1:&lt;/span&gt;    
 &lt;span class="c1"&gt;//code to be executed;    &lt;/span&gt;
 &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;//optional  &lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;value2:&lt;/span&gt;    
 &lt;span class="c1"&gt;//code to be executed;    &lt;/span&gt;
 &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;//optional  &lt;/span&gt;

&lt;span class="c1"&gt;//can add more cases.....&lt;/span&gt;

&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     
&lt;span class="c1"&gt;//code to be executed if all cases are not matched;    &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/switchExample?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ example မှာဆိုရင်တော့ integer variable တစ်ခုအဖြစ် int number = 20; ဆိုတာကို ကြေညာထားပါတယ်။  switch() ထဲမှာ number variable ကို pass လုပ်ပြီး case ၃ ခုနဲ့ တိုက်စစ်ဆေးပါတယ်။ ပထမ case မှာဆိုရင် number တန်ဖိုးက ၁၀ နဲ့ညီတဲ့အခါမှာ &lt;code&gt;System.out.println("10");&lt;/code&gt; ဆိုတဲ့ operation ကိုအလုပ်လုပ်ပါလိမ့်မယ်။ ဒါပေမယ့် အခု number ရဲ့တန်ဖိုးက 20 ဖြစ်နေတဲ့အတွက် ဒုတိယ case မှာ မှန်သွားပါလိမ့်မယ်။ အဲ့တော့ program ကို run လိုက်တဲ့အခါမှာ 20 ဆိုပြီး output ထွက်ပါမယ်။ တစ်ခုသိထားရမှာက တကယ်လို့ ဒုတိယ case မှာသာ break statement မထည့်ထားဘူးဆိုရင်အောက်က တတိယ case အထိပါဆက်သွားမှာဖြစ်ပြီး 30 ကိုပါ output ထုတ်ပေးသွားမှာဖြစ်ပါတယ်။ အဲ့ဒါကြောင့် case တစ်ခုချင်းစီသာ အလုပ်လုပ်လိုပါက case ရဲ့အဆုံးရောက်တိုင်း break; ကိုမဖြစ်မနေထည့်ပေးဖို့ လိုအပ်ပါတယ်။&lt;br&gt;
Default မှာကတော့ အပေါ် မှာ ပြောထားသလိုပဲ case တွေအားလုံး စစ်ဆေးတာ မအောင်မြင်ခဲ့ရင် default ထဲက operations တွေကို အလုပ် လုပ်ပါလိမ့်မယ်။&lt;/p&gt;

&lt;p&gt;ဒီလောက်ဆို conditional statements တွေအကြောင်း နားလည်သွားပြီလို့ထင်ပါတယ်။ နောက်တစ်ပိုင်းမှာ loop statements တွေအကြောင်း ဆက်ပြောပြသွားပါမယ်။&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Loops in Java</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Fri, 02 Jul 2021 05:35:32 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/loops-in-java-1o1h</link>
      <guid>https://dev.to/heinkhantzaw/loops-in-java-1o1h</guid>
      <description>&lt;p&gt;Loop ဆိုတာက သတ်မှတ်ထားတဲ့ condition မဖြစ်မချင်း ထပ်ကာထပ်ကာ အလုပ်လုပ်စေဖို့ ညွှန်ကြားပေးနိုင်တဲ့ iteration statement တွေဖြစ်ပါတယ်။&lt;br&gt;
program မှာ loop တွေ ကို ပုံစံ အမျိုးမျိုး သုံးလေ့ရှိပါတယ် ။ ဥပမာ - program ထဲမှာ ၁ ကနေ ၁၀၀ အထိ နံပါတ်များကို print ချင်တယ်ဆိုရင် &lt;code&gt;system.out.println()&lt;/code&gt; အကြောင်း ၁၀၀ ရေးရမယ့်အစား loop အခါ ၁၀၀ ပတ်ပြီးထုတ်လို့ရပါတယ်။&lt;/p&gt;

&lt;p&gt;Java မှာ &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;for loop&lt;/li&gt;
&lt;li&gt;while loop&lt;/li&gt;
&lt;li&gt;do-while loop
ဆိုပြီးအဓိက loop သုံးမျိုးရှိပါတယ်။&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  for loop
&lt;/h2&gt;

&lt;p&gt;for loop ကိုဘယ်အချိန်မှာ အသုံးပြုသင့်လဲဆိုတော့ program ထဲမှာ loop လုပ်ရမယ့် အရေအတွက် အတိအကျသိရင် for loop ကိုအသုံးပြုသင့်တယ်။&lt;br&gt;
for loop ထဲမှာလည်း အမျိုးအစားအလိုက် အောက်ပါ ၃ မျိုးရှိပါတယ်။&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;traditional for loop&lt;/li&gt;
&lt;li&gt;enhanced for loop&lt;/li&gt;
&lt;li&gt;labeled for loop&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Traditional for loop
&lt;/h3&gt;

&lt;p&gt;Traditional/Simple for loop က counter အပေါ်မှာမူတည်ပြီး loop ပတ်တဲ့ပုံစံဖြစ်ပါတယ်။ သူ့မှာ initialization (စမှတ်) ရယ် condition စစ်ဆေးခြင်း(ဆုံးမှတ်)ရယ် increment/decrement value (ထပ်တိုး/ထပ်လျော့တန်ဖိုး) ဆိုပြီးသုံးခုပါ၀င်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialization&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;decrement&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;ဒါဆိုရင် ဥပမာ တစ်ခုလုပ်ကြည့်ရအောင် ကျွန်တော်တို့  hello world ဆိုတဲ့စာသားကို 10 ခါထုတ်မယ့် program ပေါ့။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/forLoopOne?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ program မှာ startpoint ဆိုတဲ့ int variable တစ်ခုကိုတည်ဆောက်ပြီး 0 ပေးလိုက်ပါတယ်။ condition ကိုတော့ startpoint က 10 အောက်ငယ်တဲ့အထိအလုပ်လုပ်မယ်လို့ပြောထားပါတယ်။ increment value မှာ startpoint++ လို့ပြောတာက loop တစ်ခါပတ်ပြီးတိုင်း startpoint value ကို 1 တိုးမယ်လို့ပြောထားတာပါ။ ဒီတော့ program flow ကိုကြည့်မယ်ဆိုရင် for loop statement ရောက်တာနဲ့ အရင်ဆုံး startpoint တန်ဖိုး 0 နဲ့စမယ်။ condition ကိုစစ်ဆေးတော့ 10 ထက်ငယ်တယ်။ အဲ့တော့ condition မှန်သွားလို့ loop ထဲဆက်သွားမယ်။ နောက်ပြီး increment/decrement နေရာရောက်တော့ startpoint++ ဆိုတာ ကြောင့်ချက်ခြင်းမတိုးသေးဘဲ loop statement အဆုံးမှ 1 တိုးမှာပါ။တကယ်လို့ ++startpoint ဆိုရင်တော့ ဘာမှမလုပ်ခင် startpoint value အရင်တိုးမှာဖြစ်ပါတယ်။ အဲတော့ဆက်သွားရမယ်ဆိုရင် &lt;code&gt;system.out.println(“hello world”);&lt;/code&gt; ဆို တဲ့ output တစ်ခုထွက်လာမယ်။ ပြီးတော့ နောက်ထပ် loop တစ်ခါပတ်တော့ increment value 1 တိုးခဲ့ပြီဖြစ်လို့ startpoint = 1 အဖြစ်နဲ့ condition စစ်ဆေးတယ် 10 အောက်ကငယ်နေသေးတာကြောင့် loop ဆက်သွားမယ် နောက်ထပ် &lt;code&gt;system.out.println(“hello world”);&lt;/code&gt; ကို ထပ်ထုတ်မယ်။ ဒီလိုနဲ့ startpoint = 9 အထိပတ်တဲ့ အခါမှာ နောက်ဆုံး 10 ကြိမ်မြောက်ရောက်တဲ့အခါမှာ startpoint &amp;lt; 10 မဖြစ်တော့တာမို့လို့ loop ရပ်သွားပါတယ်။&lt;/p&gt;

&lt;p&gt;ဒီနေရာမှာ တစ်ခု ပြောချင်တာက တကယ်လို့ ကိုယ်က decrement value သုံးပြီး loop ပတ်ချင်လည်းပတ်လို့ရပါတယ်။ အဲ့အခါဘယ်လိုပုံစံဖြစ်သွားမလဲဆိုတော့ &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/forLoopTwo?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h4&gt;
  
  
  Infinite for Loop
&lt;/h4&gt;

&lt;p&gt;နောက်တစ်ခုကတော့ ကျွန်တော်တို့ for() ထဲမှာ ဘာမှမကြေညာဘဲ semicolons နှစ်ခုပဲ ရေးထားမယ်ဆိုရင်ကော? ဘယ်လိုဖြစ်သွားမလဲ? အဖြေကတော့ ဒီ loop ဟာ ဘယ်တော့မှ ရပ်တော့မှာမဟုတ်တဲ့  infinite loop ဖြစ်သွားပါလိမ့်မယ် ။ဒါပေမယ့်ရပ်ဖို့အတွက်ကတော့ Ctrl+c (or) Command+c  ကိုတွဲနှိပ်ရင်တော့ ရပ်ပါတယ်နော်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;ဒါဆိုရင် သင်မရပ်မချင်း ဘယ်တော့မှရပ်မှာမဟုတ်တဲ့ program တစ်ခုစမ်းရေးကြည့်ရအောင်။&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/forLoopInfinite?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;Program run လိုက်မယ်ဆိုရင်တော့ မရပ်ဘဲ run နေတဲ့ loop တစ်ခုကို ရမှာဖြစ်ပါတယ်။ မျက်စိနောက်လောက်အောင်ကိုတက်လာပါလိမ့်မယ်။ Ctrl+c (or) Command+c သာနှိပ်လိုက်ပါ။&lt;/p&gt;

&lt;h4&gt;
  
  
  Nested for Loop
&lt;/h4&gt;

&lt;p&gt;Nested Loop ဆိုတာ Loop ထဲမှာ Loop တွေထပ်ပတ်ထားတဲ့ဟာပါ။ အများဆုံးကတော့ for loop တွေမှာတွေ့ရပါတယ်။ကျွန်တော်တို့ nested loop တွေကိုတစ်ချက်ရေးကြည့်ကြရအောင်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/forLoopNested?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;ဒီ program မှာ for loop နှစ်ခါပတ်ထားပါတယ်။ ပထမ for loop မှာက အရင်ဆုံး i တန်ဖိုးနဲ့ ပတ်တာပါ။ i &amp;lt; 5 ဆိုတော့ 5 ခါပေါ့။ အဲ့ဒီ i နဲ့ပတ်တဲ့ for loop ထဲမှာမှ j နဲ့ထပ်ပတ်တာပါ j &amp;lt; 5 ကလည်း j ကို ၅ခါထပ်ပတ်ထားပါတယ်။ အဲဒီတော့ i loop တစ်ခါပတ်တိုင်း j loop ထဲမှာ ရှိတဲ့ အလုပ် ၅ ခုလုပ်ပါတယ်။ j loop ထဲကိုကြည့်လိုက်ရင် &lt;code&gt;System.out.print("*"+" ");&lt;/code&gt; ဖြစ်တဲ့အတွက် * ငါးခုကို ဘေးတိုက် * * * * * ဆိုပြီး output ထွက်ပါမယ်။ သူ အောက်မှာမှ i loop ထဲမှာ &lt;code&gt;println()&lt;/code&gt; ရေးထားတဲ့အတွက် နောက်တစ်ကြောင်းဆင်းသွားပါမယ်။ ဒီလိုနဲ့ i loop ၅ပတ်လည်း ပြည့်ရော * * * * * ငါးကြောင်း output ထွက်လာပြီး လေးထောင့်တုံးပုံစံတွေ့ရမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;ဒါကတော့ traditional for loop အသုံးပြုနည်းဖြစ်ပါတယ်။&lt;/p&gt;

&lt;h3&gt;
  
  
  Enhanced For Loop
&lt;/h3&gt;

&lt;p&gt;Enhanced For Loop(For-Each Loop) ကို array (သို့) collection တွေကိုမှာ အသုံးပြုလေ့ရှိပါတယ်။ ဘာလို့လဲဆိုတော့ အဲ့ loop က increment value မလိုအပ်သလို တခြားဘာမှလည်းမလိုအပ်ပါဘူး။ For-Each Loop က array ရဲ့ index ပေါ်မှာ အလုပ်လုပ်တာမဟုတ်ဘဲ elements တွေပေါ် မှာလုပ်တာဖြစ်ပါတယ်။ ဒီ Loop ကိုသုံးလိုက်တဲ့အခါမှာ array ထဲက elements တွေကို သတ်မှတ်ထားတဲ့ variable ထဲကို တစ်ခုချင်း return ပြန်ပေးသွားမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataType&lt;/span&gt; &lt;span class="nl"&gt;variable:&lt;/span&gt; &lt;span class="n"&gt;array_name&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example တစ်ခုရေးကြည့်ရအောင် &lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/forEachLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ example မှာဆို ကျွန်တော်က arr လို့ခေါ်တဲ့ integer array တစ်ခုကို တည်ဆောက်ထားတယ်။ အဲဒီထဲမှာ integer value တွေဖြစ်တဲ့ 12,23,44,55,44,66 သိမ်းထားပါတယ်။ အဲဒါကို For-Each Loop နဲ့ loop ပတ်ဖို့အတွက် for() ထဲမှာ int i ဆိုပြီး variable တစ်ခုကိုတည်ဆောက်ပါတယ် ပြီးတော့ ကျွန်တော်တို့ရဲ့ array နာမည်ကိုထည့်ပေးလိုက်တာပါဘဲ ဒီတော့ ဘယ်လိုဖြစ်သွားလဲဆိုတော့ loop ပတ်တဲ့အခါမှာ array ထဲမှာရှိတဲ့ elements တွေက ကျွန်တော်တို့တည်ဆောက်ထားတဲ့ variable i ထဲကိုရောက်ပြီး return ပေးပါတော့တယ် ဒီတော့ ကျွန်တော်တို့ array ထဲက element တွေ output ထွက်လာပြီဖြစ်ပါတယ်။&lt;/p&gt;

&lt;h3&gt;
  
  
  Labeled For Loop
&lt;/h3&gt;

&lt;p&gt;Labeled For Loop ကတော့အသုံးနည်းတဲ့ loop တစ်ခုပါ။ သူကကျတော့ loop တစ်ခုချင်းစီကို label ပေးလို့ရတဲ့ loop ဖြစ်ပါတယ်။ ရေးရမယ့် ပုံစံကတော့ for loop မတိုင်မီ label (နာမည်) တစ်ခု အရင်ပေးရပါတယ်။ အကယ်၍ program ထဲမှာ nested for loop ရှိပါက loop တစ်ခုချင်းစီကို label တပ်ပြီး break/continue keyword တွေနဲ့ control လို့ရပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;labelName:&lt;/span&gt;  
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialization&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;decrement&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;  
&lt;span class="c1"&gt;//code to be executed  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/labeledForLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီမှာဆိုရင် အပြင်ဘက်က i နဲ့ပတ်တဲ့ loop ကို aa လို့ label တပ်ထားပြီး အထဲက j နဲ့ပတ်တဲ့ loop ကိုတော့ bb ဆိုပြီး label တပ်ထားပါတယ်။ bb loop ထဲမှာ if(i==2 &amp;amp;&amp;amp; j==2) ဆိုတဲ့ condition တစ်ခုစစ်ပြီး တကယ်လို့ condition ကိုက်ညီတယ်ဆိုရင် break aa; ဆိုပြီး aa loop ကို break လုပ်ထားပါတယ်။  break statement ဆိုတာကတော့ loop block တွေထဲမှာ အကြောင်းတစ်မျိုးမျိူးကြောင့် break statement ကိုရောက်ပြီဆိုတာနဲ့ လက်ရှိ loop ကနေ ထွက်ပေးနိုင်ပါတယ်။ အထက်ပါ example မှာဆိုရင် i နဲ့ j တန်ဖိုးနှစ်ခုစလုံး 2 နဲ့ညီသွားတဲ့အခါ aa loop ကို break statement နဲ့ရပ်လိုက်မှာဖြစ်ပါတယ်။ အဲ့တော့ output ထွက်တဲ့အခါ i = 1 မှာ j နဲ့ပတ်တဲ့ bb loop က သုံးကြိမ် အထိပတ်ပြီး i = 2 ဖြစ်တဲ့အချိန်မှာ bb loop ထဲမှာ j = 1 အထိပဲ output ထွက်မှာကို မြင်တွေ့ရပါလိမ့်မယ်။&lt;/p&gt;

&lt;p&gt;For Loop တွေအကြောင်း ကတော့ ဒီမှာ ပြီးပါပြီ။&lt;/p&gt;

&lt;h2&gt;
  
  
  While Loop
&lt;/h2&gt;

&lt;p&gt;While Loop ကို ကျွန်တော်တို့ program ထဲက condition တစ်ခုဟာမှန်နေသရွေ့ ထပ်ကာထပ်ကာအလုပ်လုပ်စေလိုသောအခါ အသုံးပြုပါတယ်။ ပြီးတော့ ဒီ while loop ကို အကြိမ်အရေအတွက် အတိအကျမရှိတဲ့ loop တွေအတွက်အသုံးပြုကြတာ ဖြစ်ပါတယ်။ ပြီးတော့ဘယ်တော့မှမရပ်တဲ့ Loop တွေအတွက်လဲ အသုံးပြုနိုင်ပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/whileLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီမှာ While Loop ကို တည်ဆောက်ဖို့အတွက် while ကိုရေးပြီး condition ထည့်ရပါတယ် သူ့ထဲက အခြေအနေ မှန်ကန်နေသရွေ့ ကျွန်တော်တို့ Loop က အလုပ်လုပ်နေအုန်းမှာပါ။ ဒါပေမယ့် ဒီမှာ for လို တစ်ခါထဲတည်ဆောက် လိုက်လို့မရဘူး။ &lt;code&gt;int i = 1&lt;/code&gt; ဆိုတာ အရင်ဆုံးကြေညာပြီး while loop ထဲမှာ ဘယ်အောက်ငယ်တဲ့ အထိဆိုပြီး condition တစ်ခုသတ်မှတ်ပေးရတယ်။ အခု i&amp;lt;=5 ဆိုတော့ i က 5 နဲ့ညီတဲ့ အထိ loop ပတ်မယ်ဆိုပြီး ရေးလိုက်တာဖြစ်ပါတယ်။ပြီးတော့ တန်ဖိုးတိုးသွား မယ့် i ကို output ထုတ်ပါတယ် ပြီးတော့ counter တိုးဖို့ လျော့ဖို့အတွက် increment/decrement ကိုရေးဖို့လိုပါသေးတယ်။ ဒီတော့အောက်မှာ &lt;code&gt;i++;&lt;/code&gt; ဆိုပြီးရေးပေးရပါတယ်။&lt;/p&gt;

&lt;h3&gt;
  
  
  Infinite While Loop
&lt;/h3&gt;

&lt;p&gt;Infinite While Loop ရဖို့က Condition နေရာမှာ true လုပ်ထားလိုက်ရုံပါပဲ။ အဲ့လိုသာရေးထားလိုက်မယ်ဆိုရင် ဘယ်တော့မှ while loop ထဲက ထွက်နိုင်မှာ မဟုတ်တော့ပါဘူး။&lt;br&gt;
ထွက်ချင်ရင်တော့ ခုနက Infinite for Loop တုန်းကလိုပဲ Ctrl+c ကိုတွဲနှိပ်လိုက်ရုံပါပဲ။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// code to be executed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/infiniteWhileLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Do-While Loop
&lt;/h2&gt;

&lt;p&gt;ဒီ Do-While Loop ကလည်း တခြား Loop တွေလိုဘဲ ထပ်ခါထပ်ခါလုပ်မယ့် လုပ်တွေ အတွက်သုံး နိုင် ပါတယ်။ဒါပေမယ့် တစ်ခုရှိတာကတော့ ကျွန်တော်တို့ ထပ်ခါထပ်ခါလုပ်ဖို့ အကြိမ်ရေအတိကျမရှိတဲ့အခါမျိုး နဲ့ condition မမှန်ကန်ခဲ့ရင်တောင် အနည်းဆုံးတစ်ခေါက်ကတော့ လုပ်ကိုလုပ်ရမယ်ဆိုတဲ့အခြေအနေမျိုးတွေအတွက် အသုံးပြုရပါတယ်။&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//code to be executed&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;သူ့ရဲ့ syntax တည်ဆောက်ပုံအရ condition စစ်ဆေးခြင်းက နောက်မှလာတာဖြစ်တဲ့ အတွက် condition စစ်ဆေးမှုက false ဖြစ်နေခဲ့ရင်တောင် loop က အနည်းဆုံး 1 ကြိမ်တော့အလုပ်လုပ်မှာပါ။&lt;br&gt;
အရင်ဆုံး condition မှန်တဲ့ program တစ်ခုရေးပြီးနောက်မှ condition မှားတာတစ်ခုရေးကြပါမယ်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/doWhileLoop?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;ဒီ program က i တန်ဖိုး 5 နဲ့မညီမချင်း အလုပ်လုပ်မယ့် program ဖြစ်ပါတယ်။ ဒါကတော့ခုနက while loop ပုံစံနဲ့အတူတူပဲဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;အခု ကျွန်တော်တို့ condition အမှားတစ်ခုရေးရအောင်။&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@HeinKhantZaw/wrongDoWhile?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;ဒီမှာဆို condition စစ်ဆေးထားတာက i&amp;lt;=5 ဖြစ်ပါတယ်။ ဒါပေမယ့် အခု i တန်ဖိုးက စကြေညာတည်းက 6 ဖြစ်နေပြီဆိုတော့ ဘယ်လိုနည်းနဲ့မှ condition မမှန်တော့ပါဘူး။ ဒါပေမယ့် do block ထဲက code ကိုတော့ တစ်ကြိမ်အလုပ်လုပ်သွားတာတော့တွေ့ရမှာဖြစ်ပါတယ်။&lt;/p&gt;

&lt;p&gt;ကဲ....ဒီလောက်ဆိုရင် loop ကောင်းကောင်းပတ်တတ်သွားပြီထင်ပါတယ်။ အဲ့တော့ ဒီ &lt;a href="http://www.beginwithjava.com/java/loops/questions.html"&gt;link&lt;/a&gt; ထဲက loop နဲ့ ပတ်သက်တဲ့ exercise လေးတွေလုပ်ကြည့်ရင်ပိုပြီးနားလည်တတ်မြောက်သွားမယ်ထင်ပါတယ်။&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>java</category>
    </item>
    <item>
      <title>Things to know before using public Wi-Fi</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sun, 06 Jun 2021 19:39:46 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/things-to-know-before-using-public-wi-fi-2k95</link>
      <guid>https://dev.to/heinkhantzaw/things-to-know-before-using-public-wi-fi-2k95</guid>
      <description>&lt;p&gt;Accessing wifi is not a problem while you are at home - it’s secure, easy to connect and no strangers are using your home network. However, when you are outside, using public Wi-Fi will give you a nightmare if you aren't aware of the risk of security issues. So, if you are considering whether to connect to the public Wi-Fi network at the shopping mall, the airport, etc. beware of the potential risk to your device because hackers love public Wi-Fi!&lt;br&gt;
Although it’s risky to use Wi-Fi in public, I’m going to explain how to safely use public Wi-Fi services. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use VPN
&lt;/h2&gt;

&lt;p&gt;The most effective trick to staying safe on public Wi-Fi is to use a VPN on your devices. Although virtual private networks are not infallible, they can protect your privacy. They encrypt data that passes through the network and connect your device to a secure server, making it harder for the hackers on the same network or anyone who controls the network to see what you're doing. So, using a VPN will secure your information from other users of the same connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Always HTTPS
&lt;/h2&gt;

&lt;p&gt;When the site you're visiting uses an unencrypted HTTP connection, most of the browsers let you know with the "Not Secure" label beside the URL. Beware of that warning especially if you are connected to public Wi-Fi. When you browse over HTTPS, people on the same Wi-Fi network can’t sniff the data that travels between you and the server of the website you're connecting to. If it’s over HTTP, it’s gonna be very easy for them to track what you're surfing. So, always verify that the website you surf uses HTTPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never give away too much info
&lt;/h2&gt;

&lt;p&gt;It’s better not to access personal bank accounts, or give sensitive personal data (your address, phone number or email, etc.) on public Wi-Fi. If you have no choice, you should consider using an alternative email address or phone number that isn't your primary one. And also, it’s not recommended to do online shopping over public Wi-Fi. Of course, shopping doesn’t seem like a big deal, but making purchases online requires personal information - bank account or credit card numbers. &lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t let your guard down
&lt;/h2&gt;

&lt;p&gt;Never leave your device unattended in public. Even if you’re on a secure network or unsecured network, that won’t stop someone from taking your device or sneaking a peek at your device. &lt;br&gt;
Always keep your device near you.&lt;/p&gt;

&lt;p&gt;If you follow the steps mentioned above, you will have more chances of staying out of trouble while you're using public Wi-Fi. However, Always keep in mind that no public Wi-Fi network is secure and you should always use public Wi-Fi with caution. &lt;br&gt;
&lt;strong&gt;And Remember - any device could be at risk too.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>awareness</category>
    </item>
    <item>
      <title>Speeding up Android Studio on 4GB RAM</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Mon, 11 Jan 2021 10:59:38 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/speeding-up-android-studio-on-4gb-ram-1gl2</link>
      <guid>https://dev.to/heinkhantzaw/speeding-up-android-studio-on-4gb-ram-1gl2</guid>
      <description>&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5dg3vzu4tx28xv3w9jfs.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5dg3vzu4tx28xv3w9jfs.jpg" alt="meme2"&gt;&lt;/a&gt;&lt;br&gt;
Although Android Studio is a powerful IDE, there are many memes about long building time, slow speed, taking huge amount RAM etc. &lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://developers.android.com" rel="noopener noreferrer"&gt;developers.android.com&lt;/a&gt;, minimum requirement for android studio is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 GB RAM minimum, 8 GB RAM recommended&lt;/li&gt;
&lt;li&gt;2 GB of available disk space minimum,&lt;/li&gt;
&lt;li&gt;4 GB Recommended (500 MB for IDE + 1.5 GB for Android SDK and emulator system image)&lt;/li&gt;
&lt;li&gt;1280 x 800 minimum screen resolution &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However Windows usually takes 2GB and Android Studio will alone take up to 1GB and if you run with emulator, it will consume about 1.5GB - 2 GB. So basically, when you try to run Android Studio in Windows with emulator, it's gonna be a very huge pain in the ass. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flw2sy8l6e3ktbmok3odw.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flw2sy8l6e3ktbmok3odw.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, How can we speed up our Android Studio in a laptop with 4GB RAM?&lt;br&gt;
The best way is to upgrade your RAM to 8GB as recommended in official website. (Just kidding..xD I'll be more serious after this).&lt;br&gt;
There are several ways to speed up your Android Studio.&lt;br&gt;
When I learned android development for the first time, my laptop had only 4GB RAM and I went through so much trouble to run an android app. It took about 15 minutes to build gradle and opening the emulator will take about another 15 minutes. So, here comes the tip.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If your laptop has only 4GB RAM, don't run your project with emulator or it will end up in a complete disaster!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Running with a physical device will reduce both your anger and loading time of the android project.&lt;br&gt;
So, I recommend you to use your android device instead of emulator to test the apps.&lt;/p&gt;

&lt;p&gt;Another way to speed up android studio is to run it in different OS rather than Windows. As I've said above, Windows OS usually takes 2GB as there are many background processes and system process running in Windows that you can't stop. So, another tip is to dual boot your laptop with a Linux distro or just remove Windows completely and use Linux instead :P &lt;br&gt;
Currently I use Debian OS with Windows dual boot and my laptop RAM is 8GB. According to my experience, starting Android Studio and running an project in Debian is much faster than in Windows.&lt;br&gt;
So, here is another popular tip.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Use Linux. Run Android apps with your android device instead of emulator. Then, 4GB RAM will be sufficient to run smoothly without any lags.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, if you are too attached to Windows, it's ok. Let it be.&lt;br&gt;
I'll telling another way to speed up Android Studio in your Windows Laptop. &lt;/p&gt;

&lt;p&gt;Go to Android Studio first.&lt;br&gt;
Then, click &lt;code&gt;Power save mode&lt;/code&gt;. It will reduce lots of background work in Android Studio.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frmk9a8ixkysjzglx8tx0.JPG" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frmk9a8ixkysjzglx8tx0.JPG" alt="Power save mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that , click &lt;code&gt;File &amp;gt; Setting &amp;gt; Plugins&lt;/code&gt; .&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foxcqlzyc8dnt3jr260zi.JPG" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foxcqlzyc8dnt3jr260zi.JPG" alt="Plugins"&gt;&lt;/a&gt;&lt;br&gt;
As I disabled the plugins that I don't need, you won't see so many enabled plugins in my laptop.&lt;br&gt;
However, in you laptop, you will see so many enabled plugins and these are also the things which slows down your IDE. You will see IDE gets slower when adding plugins. So, if you disable all the plugins that you don't use (I know you are not using all these plugins to develop your app), I guarantee that Android Studio will speed up for sure.&lt;/p&gt;

&lt;p&gt;I disabled the following plugins in my IDE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android APK Support&lt;/li&gt;
&lt;li&gt;Android Games&lt;/li&gt;
&lt;li&gt;Android NDK&lt;/li&gt;
&lt;li&gt;App Links Assistant&lt;/li&gt;
&lt;li&gt;Change Reminder&lt;/li&gt;
&lt;li&gt;Copyright&lt;/li&gt;
&lt;li&gt;Coverage&lt;/li&gt;
&lt;li&gt;Editor Config&lt;/li&gt;
&lt;li&gt;Firebase App Indexing&lt;/li&gt;
&lt;li&gt;Firebase Testing&lt;/li&gt;
&lt;li&gt;Google Cloud Tools Core&lt;/li&gt;
&lt;li&gt;Google Cloud Tools for Android&lt;/li&gt;
&lt;li&gt;Google Developer Samples&lt;/li&gt;
&lt;li&gt;Google Login&lt;/li&gt;
&lt;li&gt;Google Services&lt;/li&gt;
&lt;li&gt;Mercurial&lt;/li&gt;
&lt;li&gt;Settings repository&lt;/li&gt;
&lt;li&gt;Subversion&lt;/li&gt;
&lt;li&gt;Task management&lt;/li&gt;
&lt;li&gt;Test recorder&lt;/li&gt;
&lt;li&gt;TestNG&lt;/li&gt;
&lt;li&gt;YAML
After that, click &lt;code&gt;Apply&lt;/code&gt; and restart your Android Studio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But wait. What if you need Any Plugin Later? &lt;br&gt;
&lt;em&gt;Easy Buddy! Relax.&lt;/em&gt;&lt;br&gt;
For example, if you are adding google services or firebase in your app in the future, just go back to plugins and enable again. &lt;/p&gt;

&lt;p&gt;If you are also using any antivirus, make sure to add Exception of all android studio directories. So it won’t scan those folders while you are using Android Studio. This will make it even faster.&lt;br&gt;
As for default Windows Defender, you can follow &lt;a href="https://docs.microsoft.com/en-us/windows/android/defender-settings#:~:text=Select%20Virus%20and%20threat%20protection,%2C%20File%20type%2C%20or%20Process." rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to add exception for Android Studio.&lt;/p&gt;

&lt;p&gt;You can follow these tips from &lt;a href="https://developer.android.com/studio/build/optimize-your-build" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; to improve the build speed of your Android Studio project.&lt;/p&gt;

&lt;p&gt;Here's my final tip 😛:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F30iz041vuyisrfrwxbro.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F30iz041vuyisrfrwxbro.jpg" alt="final meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you guys won't suffer from Android Studio nightmares. Peace &amp;lt;3&lt;/p&gt;

</description>
      <category>android</category>
      <category>androidstudio</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introduction to Android Lifecycle</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sat, 09 Jan 2021 03:48:32 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/introduction-to-android-lifecycle-3jka</link>
      <guid>https://dev.to/heinkhantzaw/introduction-to-android-lifecycle-3jka</guid>
      <description>&lt;p&gt;The android activity lifecycle includes the following callbacks: &lt;code&gt;onCreate()&lt;/code&gt;, &lt;code&gt;onStart()&lt;/code&gt;, &lt;code&gt;onResume()&lt;/code&gt;, &lt;code&gt;onPause()&lt;/code&gt;, &lt;code&gt;onStop()&lt;/code&gt;, &lt;code&gt;onRestart()&lt;/code&gt;, and &lt;code&gt;onDestroy()&lt;/code&gt;.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkzr2v0idc98mkk6tc98v.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkzr2v0idc98mkk6tc98v.png" alt="Activity Lifecycle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  onCreate()
&lt;/h2&gt;

&lt;p&gt;The lifecycle of an android activity begins here. This is where any layout resources (Buttons, textViews, editText, etc.) and background threads are initialized. &lt;/p&gt;

&lt;h2&gt;
  
  
  onStart()
&lt;/h2&gt;

&lt;p&gt;Called right after onCreate(). In this state the activity becomes visible to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  onRestart()
&lt;/h2&gt;

&lt;p&gt;Called after an activity has been stopped. This call reverts the activity to its visible lifetime.&lt;/p&gt;

&lt;h2&gt;
  
  
  onResume()
&lt;/h2&gt;

&lt;p&gt;Called when the user returns to an activity after briefly exiting it. The app stays in this state until something happens to take focus away from the app. Such an event might be, for instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.&lt;/p&gt;

&lt;h2&gt;
  
  
  onPause()
&lt;/h2&gt;

&lt;p&gt;Called when the user leaves the current activity to another activity or leaves the app for a while. It indicates that the activity is no longer in the foreground and certain processes that are not needed while the activity is not in the foreground will be stopped.   &lt;/p&gt;

&lt;h2&gt;
  
  
  onStop()
&lt;/h2&gt;

&lt;p&gt;Called when the activiy becomes invisible to the user. The activity and its resources may still be running in the background even though it is not visible. After onStop() is called, the activity will call onRestart() if it needs to be loaded again.&lt;/p&gt;

&lt;h2&gt;
  
  
  onDestroy()
&lt;/h2&gt;

&lt;p&gt;The end of the activity lifecycle. This activity is used to stop all resources and tasks started in onCreate(). After onDestroy() is called, the activity will call onCreate() if it needs to be loaded again.&lt;br&gt;
The system invokes this callback either because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The activity is finishing (due to the user completely dismissing the activity or due to finish() being called on the activity), or&lt;/li&gt;
&lt;li&gt;The system is temporarily destroying the activity due to a configuration change (such as device rotation or multi-window mode)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can learn more about android life cycle &lt;a href="https://developer.android.com/guide/components/activities/activity-lifecycle#java" rel="noopener noreferrer"&gt;here&lt;/a&gt; !&lt;/p&gt;

</description>
      <category>android</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How encryption algorithms provide confidentiality</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Mon, 04 Jan 2021 13:46:25 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/how-encryption-algorithms-provide-confidentiality-4j1b</link>
      <guid>https://dev.to/heinkhantzaw/how-encryption-algorithms-provide-confidentiality-4j1b</guid>
      <description>&lt;p&gt;As computer networks becomes essential in everyday life, it is important to secure every aspect of data and information online. This is where encryptions algorithms become useful. Once data is encrypted, only authorized parties who have a “key” can read it or use it. It means that if the encryption method is effective, it will completely protect data from unauthorized access. This necessarily requires that the message be somehow encrypted so that in case if the message is intercepted, it cannot be understood by eavesdroppers. This aspect of confidentiality is probably the most commonly perceived meaning of the term secure communication. &lt;/p&gt;

&lt;p&gt;So, how encryption algorithms provide confidentiality? First of all, there are two classes of encryption algorithms – Symmetric Encryption Algorithm and Asymmetric Encryption Algorithm. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric Encryption Algorithm includes DES, AES, etc. &lt;/li&gt;
&lt;li&gt;Asymmetric Encryption Algorithm includes RSA, Diffie–Hellman, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although, all these algorithms involve substituting one thing for another (e.g., taking a piece of plaintext and then substituting the appropriate ciphertext to create the encrypted message), Symmetric Encryption Algorithm use the same cryptographic key for encrypting and decrypting information, whereas Asymmetric Encryption Algorithm use a private key and a public key for encryption and decryption. &lt;/p&gt;

&lt;h3&gt;
  
  
  Symmetric Encryption Algorithm
&lt;/h3&gt;

&lt;p&gt;Let’s begin with Symmetric Encryption Algorithm which is also known as shared secret key algorithm. As it is symmetric encryption, the sender and receiver use a pre-shared secret key and the length of the key is usually between 80 to 256 bits. These kinds of algorithm are faster than Asymmetric Encryption Algorithm because they base on simple mathematical operations. Let’s examine how symmetric key encryption is done today. There are two broad classes of symmetric encryption techniques: stream ciphers and block ciphers.  &lt;/p&gt;

&lt;p&gt;In Block cipher technique, encryption is done in blocks of k bits. If k = 64, then the message is broken into 64-bit blocks, and each block is encrypted independently. The example of a 64-bit block cipher is shown in the following figure. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhilztcecnmzhll5d3mak.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhilztcecnmzhll5d3mak.png" alt="Block Cipher"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, there are a number of popular block ciphers, including DES (Data Encryption Standard), 3DES, and AES (Advanced Encryption Standard). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DES uses 64-bit blocks with a 56-bit key. The resource consumption of DES algorithm is medium and it would take approximately 6.4 days to crack a DES key. &lt;/li&gt;
&lt;li&gt;3DES was developed as a more secure alternative because of DES’s small key length. In 3DES, the DES algorithm is run through three times with three keys and it will take 4.6 billion years to crack with current technology. &lt;/li&gt;
&lt;li&gt;AES uses 128-bit blocks and can operate with key that are 128, 192, and 256 bits long. Resource consumption of this algorithm is low and would take approximately 149 trillion years to crack a 128-bit AES key. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Due to the larger fixed-length input, block ciphers are generally slower than stream ciphers. &lt;/p&gt;

&lt;p&gt;In Stream cipher, encryption is done one bit at a time. For Encryption, the plaintext will undergo XOR operation with keystream bit-by-bit and produces the Cipher Text. For Decryption, the ciphertext will undergo XOR operation with keystream bit-by-bit and produces the original plain text. This type of encryption is not that common. Block ciphers are used much more frequently for symmetric encryption. &lt;/p&gt;

&lt;h3&gt;
  
  
  Asymmetric Encryption Algorithm
&lt;/h3&gt;

&lt;p&gt;Asymmetric Encryption Algorithm, also known as Public Key Encryption, works in a similar manner to symmetric-key algorithms, where plaintext is combined with a key, input to an algorithm, and outputs ciphertext. The only difference is that the keys used for the encryption and decryption are different, unlike Symmetric Encryption Algorithm. Hence the name itself imply the asymmetry of the algorithm. The key pair is comprised of a private key and a public key. The public key is made available to everyone, whereas the private key is kept secret. Below is the illustration of how Asymmetric Encryption Algorithm provide confidentiality. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiw5pb0mk7tihkejn3fq6.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiw5pb0mk7tihkejn3fq6.png" alt="Asymmetric Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The concept of Asymmetric Encryption Algorithm is quite simple. Suppose Alice wants to communicate with Bob. As shown in the figure, rather than Bob and Alice sharing a single secret key (as in the case of Symmetric Encryption Algorithm), Bob (the recipient of Alice’s messages) instead has two keys—a public key that is available to everyone in the world and a private key that is known only to Bob. In order to communicate with Bob, Alice first fetches Bob’s public key. And then she encrypts her message, m, using Bob’s public key. After that, Bob receives Alice’s encrypted message and uses his private key to decrypt Alice’s encrypted message. This is how asymmetric encryption algorithm works. While there may be many asymmetric encryption algorithms, the RSA algorithm (named after its founders, Ron Rivest, Adi Shamir, and Leonard Adleman) has become almost synonymous with public key cryptography.&lt;/p&gt;

&lt;p&gt;First, each entity needs to set up their own key pairs and share the public key with one another. The two entities need to keep their private keys secret in order to keep their communications to remain secure. Once the sender has the public key of their recipient, they can use it to encrypt the data that they want to keep secure. Once it has been encrypted with a public key, it can only be decrypted by the private key from the same key pair. Even the same public key can’t be used to decrypt the data because RSA encryption works under the premise that the algorithm is easy to compute in one direction, but almost impossible in reverse. When the recipient receives the encrypted message, they use their private key to access the data. If the recipient wants to return communications in a secure way, they can then encrypt their message with the public key of the party they are communicating with. Again, once it has been encrypted with the public key, the only way that the information can be accessed is through the matching private key. In this way, RSA encryption can be used by previously unknown parties to securely send data between themselves.  &lt;/p&gt;

&lt;p&gt;Another popular algorithm is the Diffie-Hellman Algorithm (also known as DH). The main purpose of the Diffie-Hellman key exchange is to securely develop shared secrets that can be used to derive keys. These keys can then be used with symmetric-key algorithms to transmit information in a protected manner. Symmetric algorithms tend to be used to encrypt the bulk of the data because they are more efficient than public key algorithms. Technically, the Diffie-Hellman key exchange can be used to establish public and private keys. However, in practice, RSA tends to be used instead. This is because the RSA algorithm is also capable of signing public-key certificates, while the Diffie-Hellman key exchange is not. And also, Diffie-Hellman algorithm is not as versatile as RSA as it cannot be used to encrypt messages of arbitrary length. &lt;/p&gt;

&lt;p&gt;As a conclusion, the need for secure communication and information is important for the success of every enterprise. Therefore, people use different encryption algorithms to provide confidentiality of data. As explained above, two cryptographic techniques for encrypting and decrypting data are symmetric key cryptography (shared secret key) and asymmetric key cryptography (public key and private key). DES and RSA are shown as an example for these two major classes of cryptographic techniques used in today’s networks. &lt;/p&gt;

</description>
      <category>security</category>
      <category>networking</category>
      <category>computerscience</category>
      <category>beginners</category>
    </item>
    <item>
      <title>2020 Hacktoberfest swag unboxing</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Fri, 18 Dec 2020 11:32:20 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/2020-hacktoberfest-swag-unboxing-9b1</link>
      <guid>https://dev.to/heinkhantzaw/2020-hacktoberfest-swag-unboxing-9b1</guid>
      <description>&lt;p&gt;Hello everyone! Today, I received my 2020 Hacktoberfest package from Kotis Design.&lt;br&gt;
A few months back, in October, I joined Hacktoberfest which is a month long open-source event. &lt;/p&gt;

&lt;p&gt;To explain what Hacktoberfest is, it's a perfect opportunity for students learning to code and for those who wanna get their feet wet in the ocean of open-source software development.&lt;/p&gt;

&lt;p&gt;During this event, they can learn about OSS development, git and Github. At least 4 pull requests must be submitted to public GitHub repositories to earn a free T-Shirt and stickers. &lt;/p&gt;

&lt;p&gt;Enough talking! Let's unbox the package!!&lt;/p&gt;

&lt;p&gt;So here we go! Here is the package.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4emsoutviz6i0cn1hno.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4emsoutviz6i0cn1hno.jpg" alt="Package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am going to unbox it quickly so you can see what's inside the package.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq2tvrbzyj63kldb04cwe.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq2tvrbzyj63kldb04cwe.jpg" alt="unbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's inside?&lt;/p&gt;

&lt;p&gt;So, a T-shirt. You can't see clearly here but the fabric feels so soft and nice - Medium quality, neither cheap nor expensive.&lt;/p&gt;

&lt;p&gt;Two cards from sponsors (Intel and Dev).&lt;/p&gt;

&lt;p&gt;And...&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhf232k80jgt5f932dc9r.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhf232k80jgt5f932dc9r.jpg" alt="stickers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, many stickers! I didn't expected that much to be honest. There are altogether 14 stickers from sponsors such as DEV, JetBrains, circleCI, Github, etc.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwktkf346dyu0gn4wg3j2.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwktkf346dyu0gn4wg3j2.jpg" alt="promocode"&gt;&lt;/a&gt;&lt;br&gt;
And here is a promo code from Digital Ocean! This code can be used to get $100 credits in Digital Ocean (only for new users ☹️)&lt;/p&gt;

&lt;p&gt;Ok. Now, it's time to add these cool stickers to my laptop 😉&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdqvr0aexifenavplk350.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdqvr0aexifenavplk350.jpg" alt="laptop with stickers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, that's it! If you want these cool stuffs, I highly recommend you to participate in next year Hacktoberfest. You can sign up anytime between October 1 and October 31 every year! &lt;/p&gt;

&lt;p&gt;May open source be with you....&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>Github Universe 2020 is live now</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Tue, 08 Dec 2020 19:00:06 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/github-universe-2020-is-live-now-3epe</link>
      <guid>https://dev.to/heinkhantzaw/github-universe-2020-is-live-now-3epe</guid>
      <description>&lt;p&gt;Guys! Don’t miss a minute of Github Universe 2020. The sessions are worth listening. For those who don't know what Github universe is, it is an annual community event hosted by Github. This year, the event is virtually hosted due to COVID-19 pandemic.&lt;/p&gt;

&lt;p&gt;The sessions are grouped into four channels : &lt;a href="https://githubuniverse.com/developers"&gt;Developer&lt;/a&gt;, &lt;a href="https://githubuniverse.com/enterprise"&gt;Enterprise&lt;/a&gt;, &lt;a href="https://education.github.com/university"&gt;Univers(ity)&lt;/a&gt; and &lt;a href="https://githubuniverse.com/play"&gt;Play&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here is a brief explanation about each channel (resources from github universe FAQs):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developer: geared towards open source contributors and maintainers running projects of all sizes, as well as developers looking to understand the latest software tools, techniques, and best practices.&lt;/li&gt;
&lt;li&gt;Enterprise: tailored for senior leaders and decision-makers from global companies interested in transformation, security, scalability, and productivity.&lt;/li&gt;
&lt;li&gt;Univers(ity): designed specifically for college students seeking the tools, techniques, and connections that will help expand their resumes and prepare them for their future.&lt;/li&gt;
&lt;li&gt;Play: take a break, get inspired, or discover something new with entertaining performances, tutorials, and unexpected stories, all driven by code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This event will be hosted for three days (Dec 8 - Dec 10). So, I hope you learn something from the sessions that you find interesting.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Algorithm design and optimization for beginners</title>
      <dc:creator>Hein Khant Zaw</dc:creator>
      <pubDate>Sun, 06 Dec 2020 08:07:25 +0000</pubDate>
      <link>https://dev.to/heinkhantzaw/algorithm-design-and-optimization-for-beginners-30h</link>
      <guid>https://dev.to/heinkhantzaw/algorithm-design-and-optimization-for-beginners-30h</guid>
      <description>&lt;p&gt;Hi! This is my first post on DEV. I’m going to tell why you should optimize algorithms.  As an example, I will show how to design algorithm for maximum pairwise product which is pretty basic. I’ll explain how to design algorithm for this problem and optimize until we get an efficient one. So, Let’s get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand Problem Statement
&lt;/h2&gt;

&lt;p&gt;First of all, “What is maximum pairwise product” problem? Well, the problem is to find a highest product value in a sequence of non-negative integers.&lt;/p&gt;

&lt;p&gt;Just for clarification,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input&lt;/strong&gt;: &lt;em&gt;A sequence of non-negative integers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: &lt;em&gt;The maximum value that can be obtained by multiplying two different elements from the sequence.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample:&lt;/strong&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5s49pm05il5iavpwrgj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5s49pm05il5iavpwrgj.png" alt="Sample Input Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Design the algorithm
&lt;/h2&gt;

&lt;p&gt;Ok! So, let’s start with the simplest algorithm first. It is to go through all possible pairs of the input elements A[1 . . . n] = [a 1 , . . . , a n ] and to find a pair of distinct elements with the largest product.&lt;/p&gt;

&lt;p&gt;Here is the pseudocode of the above algorithm:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjwj1ukynho87xdadg2cc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjwj1ukynho87xdadg2cc.png" alt="pseudocode"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Implement the Algorithm
&lt;/h2&gt;

&lt;p&gt;According to the pseudocode, we'll implement the algorithm in java as follows:&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@DominicChen/MaxPairwiseProduct?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Test, Debug and Optimize
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test
&lt;/h3&gt;

&lt;p&gt;Check this code on a small datasets such as [1, 3, 4, 6] to ensure that it produces correct results. Then try an input [100000, 100000]. According to the algorithm, the output should be 10000000000. But wait...what happened?? The program fails to give an output for 100 000 * 100 000 and it gives 1,410,065,408 instead of the correct result 10,000,000,000. You know why?&lt;/p&gt;

&lt;h3&gt;
  
  
  Debug
&lt;/h3&gt;

&lt;p&gt;Well, this kind of error is probably caused by &lt;em&gt;an Integer Overflow&lt;/em&gt;. Integer overflows cannot be detected until they have happened. That's why, we should always keep in mind about overflow errors in programming. So as you can see, this algorithm only works for small data and therefore, we need to assign another data type for large datasets. We are going to use &lt;em&gt;long&lt;/em&gt; here.&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@DominicChen/MaxPairwiseProduct-1?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Optimize
&lt;/h3&gt;

&lt;p&gt;Everything works well now. But you think it'll work fast and correctly when there are billions of input? As we can see there's two &lt;em&gt;nested for loops&lt;/em&gt; for finding maximum pairwise product, this still is an O(n²) algorithm. So it still has an ugly running time. For large datasets, it will take for a long time to complete. &lt;strong&gt;WE NEED A FASTER ALGORITHM!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop and Think for a while.&lt;/strong&gt; What if we find only the two largest numbers in the array and multiply them instead of multiplying each and every single possible combination.&lt;/p&gt;

&lt;p&gt;Since we need to find the largest and the second largest numbers of the array, we'll only need two scans of the sequence. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During the first scan, we find the largest number. &lt;/li&gt;
&lt;li&gt;During the second scan, we find another largest number among the remaining ones and skip the number found at the previous scan. &lt;/li&gt;
&lt;li&gt;Finally multiplying both numbers and return the result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reduces the complexity of algorithm to O(n) and our algorithm is much optimized.&lt;/p&gt;

&lt;p&gt;The pseudocode will be changed like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr27w5rts2i3c5npyk7dp.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr27w5rts2i3c5npyk7dp.png" alt="Optimized Pseudocode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the code for the optimized algorithm.&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@DominicChen/MaximumPairwiseFast?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Stress Testing
&lt;/h2&gt;

&lt;p&gt;After doing optimization,testing and debugging, it is also required to test beyond the limits of normal operation. Writing bug-free code is impossible. There is no such thing like this but you can somehow minimize the volume and the severity of the bugs present in your code. Always remember, your algorithm can sometimes fail for some test cases and you will need to know which are those cases. This is where stress testing technique becomes useful. So, what's stress testing and why do we need it? To explain, it is a technique for generating thousands of tests with the goal of finding a situation where the algorithm fails to give the correct output.&lt;/p&gt;

&lt;p&gt;Basically, a stress test consists of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At least two different implementations of an algorithm (For our scenario, one is the simple brute force algorithm and the other is the optimized algorithm)&lt;/li&gt;
&lt;li&gt;A random test generator.&lt;/li&gt;
&lt;li&gt;An infinite loop in which random test generator generate a new test case, pass into both implemented algorithms and compare the results. If the results are different, the program stops, else, the loop repeats.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For our case, we create a infinite while loop and then generate arrays with random size and assign each array with random numbers. After that, we pass the array to both implementations and then compare the results.&lt;/p&gt;

&lt;p&gt;Here is the stress test for the algorithm:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@DominicChen/stressTest?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;After running the code, you will see a test case where getMaxPairwiseProduct and MaxPairwiseProductFast produce different results, so now we can check what went wrong. Can you find anything suspicious in the dataset of different results?&lt;/p&gt;

&lt;p&gt;Well, the bitter truth is that generating tests automatically and running stress test is easy,&lt;br&gt;
but debugging is hard, right?&lt;/p&gt;

&lt;p&gt;Take a look at this stress test result(the result can be different on your computer because of a different random number generator):&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd1rr5jrboywmzlb3tjvk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd1rr5jrboywmzlb3tjvk.png" alt="Stress Test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the simple brute force algorithm gave the correct result but the optimized algorithm didn't. Why? To make a long story short, the optimized one doesn't work when the maximum numbers have the same value. The algorithm always fails on any test case where the largest number is equal to the second largest number.&lt;/p&gt;

&lt;p&gt;So, although, the first algorithm works correctly, it becomes really slow when dealing with very large datasets. The second algorithm, however, is fast but doesn't work for the above cases in stress test.&lt;/p&gt;

&lt;p&gt;What should we do now?? &lt;/p&gt;

&lt;p&gt;Ok. We just need to go back to our optimized algorithm and check the process again. And .. here we go! The condition that checks the second largest number is the reason of the wrong result! &lt;/p&gt;

&lt;p&gt;So, we are changing that code to make it correct.&lt;br&gt;
Here is the final code:&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@DominicChen/MaxPairwiseProductFinal?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;Run the stress test again and wait for a minute until we get bored. You will see there's no different results anymore.&lt;/p&gt;

&lt;p&gt;MaxPairwiseProductFast algorithm is finally correct and optimized!&lt;/p&gt;

&lt;p&gt;As for the final conclusion, even for such a simple problem like this, it is easy to make mistakes during algorithm designs and optimization. But practice makes perfect 😉. There are many ways to find the solution to this problem so I hope you can find more efficient algorithm than the example one.&lt;/p&gt;

&lt;p&gt;Thank you very much for giving your time to read my post and please forgive me if my writing is too boring or too complicated. I'll try my best to write more blog post in the future 😃&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>beginners</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
