<?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: David Hwang</title>
    <description>The latest articles on DEV Community by David Hwang (@davidhwangij).</description>
    <link>https://dev.to/davidhwangij</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%2F629218%2F9211573b-0a84-41ec-8243-dbb53f18545b.png</url>
      <title>DEV Community: David Hwang</title>
      <link>https://dev.to/davidhwangij</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidhwangij"/>
    <language>en</language>
    <item>
      <title>6/12 TIL: AWS solutions architect cert S3 part 2</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Sun, 13 Jun 2021 12:00:30 +0000</pubDate>
      <link>https://dev.to/davidhwangij/6-12-til-aws-solutions-architect-cert-s3-part-2-1939</link>
      <guid>https://dev.to/davidhwangij/6-12-til-aws-solutions-architect-cert-s3-part-2-1939</guid>
      <description>&lt;p&gt;&lt;strong&gt;S3&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption

&lt;ul&gt;
&lt;li&gt;Encryption in Transit

&lt;ul&gt;
&lt;li&gt;SSL/TLS (https)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Encryption at Rest (data being stored)

&lt;ul&gt;
&lt;li&gt;Server side: Amazon helps you encrypt the object

&lt;ul&gt;
&lt;li&gt;S3 Managed Keys - SSE-S3&lt;/li&gt;
&lt;li&gt;AWS Key Management Serviced, Managed Keys - SSE-KMS&lt;/li&gt;
&lt;li&gt;Server Side Encryption With Customer Provided Keys - SSE-C&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Client side: you encrypt the object and upload it to S3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Versioning

&lt;ul&gt;
&lt;li&gt;Stores all versions of an object (including all writes and even if you delete an object)&lt;/li&gt;
&lt;li&gt;Great backup tool&lt;/li&gt;
&lt;li&gt;Once enabled, Versioning cannot be disabled, only suspended&lt;/li&gt;
&lt;li&gt;Integrates with Lifecycle rules&lt;/li&gt;
&lt;li&gt;Versioning's &lt;strong&gt;MFA Delete&lt;/strong&gt; capability, which uses multi-factor authentication, can be used to provide an additional layer of security&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Making one version of object public **doesn't&lt;/em&gt;* make other (previous or new) objects public; you have to configure them individually&lt;/li&gt;
&lt;li&gt;*Deleting an object will create Delete Marker over it and hide all the previous versions; deleting the Delete Marker will restore the object&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Lifecycle Management with S3

&lt;ul&gt;
&lt;li&gt;Go into the Bucket &amp;gt; Management tab &amp;gt; Create Lifecycle rule&lt;/li&gt;
&lt;li&gt;Automates moving your objects between different storage tiers or permanently delete previous versions (configure the timeline)&lt;/li&gt;
&lt;li&gt;Can be applied to current and previous versions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;S3 Object Lock &amp;amp; Glacier Vault Lock

&lt;ul&gt;
&lt;li&gt;S3 Object Lock

&lt;ul&gt;
&lt;li&gt;Stores objects using a &lt;strong&gt;write once, read many (WORM) model&lt;/strong&gt;. It can help you prevent objects from being deleted or modified for a fixed amount of time or indefinitely&lt;/li&gt;
&lt;li&gt;Used to meet regulatory requirements that require WORM storage, or add an extra layer of protection against object changes and deletion&lt;/li&gt;
&lt;li&gt;Can be on individual objects or applied across the bucket as a whole&lt;/li&gt;
&lt;li&gt;Modes

&lt;ul&gt;
&lt;li&gt;Governance mode: users can't overwrite or delete an object version or alter its lock settings; you can still grant some users permission to alter the retention settings or delete an object if necessary&lt;/li&gt;
&lt;li&gt;Compliance mode: a protected object version can't be overwritten or deleted by any user, including the root user; for the duration of the retention period

&lt;ul&gt;
&lt;li&gt;Retention Periods: protects an object version for a fixed amount of time&lt;/li&gt;
&lt;li&gt;Legal Holds: works like Retention Periods, only that it remains in effect until the s3:PutObjectLegalHold permission is removed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 Glacier Vault Lock

&lt;ul&gt;
&lt;li&gt;Allows you to easily deploy and enforce compliance controls for individual S3 Glacier vaults with a Vault Lock policy. &lt;strong&gt;You can specify controls such as WORM in a Vault Lock policy and lock the policy from future edits&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;S3 Performance&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 Prefix

&lt;ul&gt;
&lt;li&gt;mybucketname/folder1/subfolder1/myfile.jpg&lt;/li&gt;
&lt;li&gt;prefix is the middle bit between the bucket name and the object&lt;/li&gt;
&lt;li&gt;S3 has extremely low latency. You can get the first byte out of S3 within 100-200ms&lt;/li&gt;
&lt;li&gt;You can achieve 3,500 PUT/COPY/POST/DELETE and 5,500 GET/HEADER requests per second per prefix&lt;/li&gt;
&lt;li&gt;You can get better performance by spreading your reads across different prefixes. For example, if you are using two prefixes, you can achieve 11,000 requests per second.&lt;/li&gt;
&lt;li&gt;S3 limitations when using SSE-KMS as your encryption&lt;/li&gt;
&lt;li&gt;When you upload a file, you will call GenerateDataKey in the KMS API&lt;/li&gt;
&lt;li&gt;When you download a file, you will call Decrypt in the KMS API&lt;/li&gt;
&lt;li&gt;Uploading/downloading will count toward the KMS quota (region-specific, it's either 5,500, 10,000, or 30,000 requests per second)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Multipart uploads

&lt;ul&gt;
&lt;li&gt;Recommended for &lt;strong&gt;uploading&lt;/strong&gt; files over 100MB, required for files over 5GB&lt;/li&gt;
&lt;li&gt;Parallelize uploads (increase efficiency)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;S3 Byte-Range Fetches&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parallelize &lt;strong&gt;downloads&lt;/strong&gt; by specifying byte ranges&lt;/li&gt;
&lt;li&gt;Speed up downloads or download partial amounts of the file&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;S3 Select &amp;amp; Glacier Select&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 Select

&lt;ul&gt;
&lt;li&gt;Enables applications to retrieve only a subset of data from an object by using simple &lt;strong&gt;SQL expressions&lt;/strong&gt;. You can achieve drastic performance increases—up to 400% improvement&lt;/li&gt;
&lt;li&gt;Without S3 Select, you would need to download, decompress, and process the entire CSV to get the data you needed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Glacier Select

&lt;ul&gt;
&lt;li&gt;Some companies in highly regulated industries—e.g. financial services, healthcare, and others—write data directly to Amazon Glacier to satisfy compliance needs like SEC Rule 17a-4 or HIPAA. Many S3 users have lifecycle policies designed to save on storage costs by moving their data into Glacier when they no longer need to access it on a regular basis&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>6/10 TIL: AWS solutions architect cert S3 Part 1</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Fri, 11 Jun 2021 10:59:11 +0000</pubDate>
      <link>https://dev.to/davidhwangij/6-10-til-aws-s3-basics-features-tiers-3748</link>
      <guid>https://dev.to/davidhwangij/6-10-til-aws-s3-basics-features-tiers-3748</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Basics of S3

&lt;ul&gt;
&lt;li&gt;S3 is a universal namespace; bucket names must be unique globally&lt;/li&gt;
&lt;li&gt;When you upload a file to S3, you will receive a HTTP 200 code if the upload was successful&lt;/li&gt;
&lt;li&gt;S3 is object based—i.e. allows you to upload files

&lt;ul&gt;
&lt;li&gt;Consists of:

&lt;ul&gt;
&lt;li&gt;Key (name)&lt;/li&gt;
&lt;li&gt;Value (data)&lt;/li&gt;
&lt;li&gt;Version ID&lt;/li&gt;
&lt;li&gt;Metadata&lt;/li&gt;
&lt;li&gt;Subresources (Access Control Lists, Torrent)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Files can be from 0 bytes to 5TB; there is unlimited storage&lt;/li&gt;
&lt;li&gt;Files are stored in Buckets (equivalent to folders)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data consistency in S3

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read after Write consistency&lt;/strong&gt; for PUTS of new objects (you are able to read the file right after writing to it; http PUTS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventual Consistency&lt;/strong&gt; for overwrite PUTS and DELETES (latest version will always be used)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;S3 guarantees:

&lt;ul&gt;
&lt;li&gt;99.99% availability for the S3 platform&lt;/li&gt;
&lt;li&gt;Amazon Guarantee 99.9% availability&lt;/li&gt;
&lt;li&gt;99.999999999% durability for S3 information (11 x 9s)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;S3 features:

&lt;ul&gt;
&lt;li&gt;Tiered Storage available&lt;/li&gt;
&lt;li&gt;Lifecycle Management&lt;/li&gt;
&lt;li&gt;Versioning&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MFA Delete&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;S3 Storage Classes (Tiers)

&lt;ol&gt;
&lt;li&gt;S3 Standard

&lt;ul&gt;
&lt;li&gt;99.99% availability, 99.999999999% durability, stored redundantly across multiple devices in multiple facilities, designed to sustain the loss of 2 facilities concurrently&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 - IA (Infrequently Accessed)

&lt;ul&gt;
&lt;li&gt;For data that is accessed infrequently, but requires rapid access when needed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 One Zone - IA

&lt;ul&gt;
&lt;li&gt;When you want a lower cost option for IA data, but not require the multiple AZ data resilience&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 - Intelligent Tiering

&lt;ul&gt;
&lt;li&gt;Automatically moving data to the most cost-effective access tier using ML&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 Glacier

&lt;ul&gt;
&lt;li&gt;Secure, durable, and low-cost storage for data archiving; retrieval times configurable from minutes to hours&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;S3 Glacier Deep Archive

&lt;ul&gt;
&lt;li&gt;Lowest-cost storage class where a retrieval time of 12 hours is acceptable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;S3 charged based on:

&lt;ul&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Requests&lt;/li&gt;
&lt;li&gt;Storage Management Pricing (different tiers)&lt;/li&gt;
&lt;li&gt;Data Transfer Pricing&lt;/li&gt;
&lt;li&gt;Transfer Acceleration

&lt;ul&gt;
&lt;li&gt;Enables fast, easy, and secure transfer of files over long distances between your end users and an S3 bucket. It takes advantage of Amazon CloudFront's globally distributed edge locations. As the data arrives at an edge location, data is routed to Amazon S3 over an optimized network path&lt;/li&gt;
&lt;li&gt;If users want to upload a large file to a bucket in London, they can upload it to an edge location and those edge locations will use amazon backbone networks to bring it into London&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Cross Region Replication

&lt;ul&gt;
&lt;li&gt;Automatically replicates objects in a bucket across different regions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>6/1 TIL: Unicode utf8mb4, sql COLLATE</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Wed, 02 Jun 2021 03:51:44 +0000</pubDate>
      <link>https://dev.to/davidhwangij/6-1-til-unicode-utf8mb4-sql-collate-mca</link>
      <guid>https://dev.to/davidhwangij/6-1-til-unicode-utf8mb4-sql-collate-mca</guid>
      <description>&lt;p&gt;Unicode&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A character set that defines different character encodings, like UTF-8, UTF-16, and UTF-32&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UTF-8&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;encodes common ASCII characters using 8-bits by assigning every character a unique number called a code point&lt;/li&gt;
&lt;li&gt;vs. utf8mb4: a preferred alternative since it stores a maximum of four bytes per code point instead of 3 (utf8 is an alias of utf8mb3)—meaning utf-8 might not support some characters from other languages and symbols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An example of a sql file with the utf8mb4 charset&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
CREATE TABLE IF NOT EXISTS dbName.tableName

(

`id` int NOT NULL AUTO_INCREMENT,

`email`          varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,

`username`       varchar(20) COLLATE utf8mb4_unicode_ci  NOT NULL,

`password`       varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,

PRIMARY KEY (`id`),

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Collation provides the sorting rules, case, and accent sensitivity properties for the data&lt;/li&gt;
&lt;li&gt;You specify the COLLATE where ci stands for 'case insensitive'&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/31 TIL: CGO &amp; GOOS in Go, Github Issue Template, Mathematical Induction</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Tue, 01 Jun 2021 03:50:55 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-31-til-cgo-goos-in-go-github-issue-template-mathematical-induction-1j6e</link>
      <guid>https://dev.to/davidhwangij/5-31-til-cgo-goos-in-go-github-issue-template-mathematical-induction-1j6e</guid>
      <description>&lt;p&gt;CGO &amp;amp; GOOS in Go&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cgo enables the creation of Go packages that call C code&lt;/li&gt;
&lt;li&gt;Set CGO_ENABLED=0 or 1 along with Go build to disable or enable the cgo tool&lt;/li&gt;
&lt;li&gt;You configure the Go Operating System using GOOS&lt;/li&gt;
&lt;li&gt;Example of a go build within a Dockerfile:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
RUN CGO_ENABLED=0 GOOS=linux go build -o fileName .

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Github Issue Template&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository"&gt;https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go Vendor&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.gopheracademy.com/advent-2015/vendor-folder/"&gt;https://blog.gopheracademy.com/advent-2015/vendor-folder/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;—Discrete Math—&lt;/p&gt;

&lt;p&gt;Quotient-Remainder Theorem:&lt;/p&gt;

&lt;p&gt;For all n ∈ ℤ, d ∈ ℤ+, there exists q,r ∈ ℤ so that n = dq + r with 0 ≤ r &amp;lt; d&lt;/p&gt;

&lt;p&gt;Modular Arithmetic&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n mod d; system of arithmetic where we are concerned with the remainder&lt;/li&gt;
&lt;li&gt;Ex) Clock (n/12 = w + r), Day of the Week (n/7 = w + r)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sequence&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;informal: an infinite ordered list of objects&lt;/li&gt;
&lt;li&gt;formal: a function f: ℤ+ → C&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mathematical Induction&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prove: P(n), ∀n ≥ a&lt;/li&gt;
&lt;li&gt;Step 1: Prove that P(a) is true—basis step&lt;/li&gt;
&lt;li&gt;Step 2: Assume P(k) is true, prove P(k+1) is true (for k ≥ a )—induction step&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/30 TIL: mysql Docker image, Unix Domain Socket</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Mon, 31 May 2021 03:24:21 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-30-til-mysql-docker-image-unix-domain-socket-5cai</link>
      <guid>https://dev.to/davidhwangij/5-30-til-mysql-docker-image-unix-domain-socket-5cai</guid>
      <description>&lt;p&gt;Docker Compose&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do a 'docker-compose -f nameOfYourDockerComposeFile build' if you need your changes in Dockerfile to be reflected—because simply doing 'docker-compose up' doesn't rebuild an image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker mysql image&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration options can be passed as flags in the command line. Ex) --character-set-server=utf8mb4&lt;/li&gt;
&lt;li&gt;When a mysql container is started for the first time, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. So we can populate our mysql services by mounting a SQL dump into that directory. In our example below, we would store our .sql files in db/init and mount it to /docker-entrypoint-initdb.d under volumes:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  db:
    container_name: mysql
    image: mysql
    restart: always
    environment:
      MYSQL_USER: user1
      MYSQL_PASSWORD: test
      MYSQL_ROOT_PASSWORD: test
      MYSQL_DATABASE: users
    ports:
      - '3306:3306'
    volumes:
      - mysql_db:/var/lib/mysql
      - ./db/init:/docker-entrypoint-initdb.d
    command:
      [
        'mysqld',
        '--character-set-server=utf8mb4',
        '--collation-server=utf8mb4_unicode_ci',
      ]
volumes:
mysql_db:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/_/mysql"&gt;https://hub.docker.com/_/mysql&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unix Domain Socket&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an inter-process communication mechanism that allows bidirectional data exchange between processes on the "same" machine—faster and lighter than IP sockets because it skips checks and operations like routing&lt;/li&gt;
&lt;li&gt;vs. IP sockets: a mechanism allowing communication between processes over the network&lt;/li&gt;
&lt;li&gt;&lt;a href="https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets"&gt;https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;blog post: &lt;a href="https://medium.com/swlh/getting-started-with-unix-domain-sockets-4472c0db4eb1"&gt;https://medium.com/swlh/getting-started-with-unix-domain-sockets-4472c0db4eb1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/28 TIL: Docker Compose,  Volumes, cURL</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Sat, 29 May 2021 02:43:01 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-28-til-docker-compose-volumes-curl-ie2</link>
      <guid>https://dev.to/davidhwangij/5-28-til-docker-compose-volumes-curl-ie2</guid>
      <description>&lt;p&gt;Docker-compose&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
version: '3'
  services:
    server:
      build: .
      volumes:
        - .:/app
      ports:
        - 9090:9090
      command: ['wait-for-it.sh', 'db:3306', '--', 'air']
      depends_on:
        - db
    db:
      image: mysql
      restart: always
      environment:
        MYSQL_USER: admin
        MYSQL_PASSWORD: password
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: sampleDb
      ports:
        - '3306:3306'
      volumes:
        - mysql_db:/var/lib/mysql
      command:
        [
          'mysqld',
          '--character-set-server=utf8mb4',
          '--collation-server=utf8mb4_unicode_ci',
        ]
  volumes:
    mysql_db:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Two containers: server &amp;amp; db&lt;/li&gt;
&lt;li&gt;server

&lt;ul&gt;
&lt;li&gt;builds the Dockerfile in the current path&lt;/li&gt;
&lt;li&gt;runs on port 9090 on both the host and within the container&lt;/li&gt;
&lt;li&gt;executes 'wait-for-it.sh' to wait on the availability of port 3306 before running 'air'--using wait-for-it.sh is just an example and this shell script has to be installed as part of the Dockerfile&lt;a href="https://github.com/vishnubob/wait-for-it"&gt;https://github.com/vishnubob/wait-for-it&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;depends on db container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;db

&lt;ul&gt;
&lt;li&gt;runs on mysql image&lt;/li&gt;
&lt;li&gt;we have a 'named volume' called mysql_db at the last line of this docker-compose.yml file and we have that mounted to 'var/lib/mysql' directory in the db container's virtual file systems (watch 3:40 here for details &lt;a href="https://www.youtube.com/watch?v=p2PH_YPCsis&amp;amp;ab_channel=TechWorldwithNanaTechWorldwithNana"&gt;https://www.youtube.com/watch?v=p2PH_YPCsis&amp;amp;ab_channel=TechWorldwithNanaTechWorldwithNana&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;cURL &amp;amp; its flags&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;curl is a tool to transfer data from or to a server, using one of the supported protocols (FTP, HTTP, SFTP, and many more)&lt;/li&gt;
&lt;li&gt;Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
RUN curl -fLo [install.sh](http://install.sh/) [https://raw.githubusercontent.com/cosmtrek/air/master/install.sh](https://raw.githubusercontent.com/cosmtrek/air/master/install.sh)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;-f allows the HTTP to fail silently on server errors&lt;/li&gt;
&lt;li&gt;-L will make curl redo the request on the new place if the server reports that the requested page has moved to a different location&lt;/li&gt;
&lt;li&gt;-o writes the output to the specified file&lt;/li&gt;
&lt;li&gt;-s is silent mode&lt;/li&gt;
&lt;li&gt;-S is used with -s and it makes curl show an error message if it fails. ex) -sSfL&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/26 TIL: Dockerfile, apt, C++ Generics, ADT in C</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Thu, 27 May 2021 01:59:28 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-26-til-dockerfile-apt-c-generics-adt-in-c-4g9d</link>
      <guid>https://dev.to/davidhwangij/5-26-til-dockerfile-apt-c-generics-adt-in-c-4g9d</guid>
      <description>&lt;p&gt;--Docker--&lt;br&gt;
Dockerfile for a Go project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
FROM golang:1.15 AS builder

RUN apt update &amp;amp;&amp;amp; apt upgrade -y &amp;amp;&amp;amp; \

apt install -y git \

WORKDIR /app

# Get install script, run, and make binary

RUN curl -fLo install.sh https://raw.githubusercontent.com/cosmtrek/air/master/install.sh \

&amp;amp;&amp;amp; chmod +x install.sh &amp;amp;&amp;amp; sh install.sh &amp;amp;&amp;amp; cp ./bin/air /bin/air

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Always combine RUN apt-get update with apt-get install in the same RUN statement as suggested in the Dockerfile best practices under the 'apt-get' section here: &lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"&gt;https://docs.docker.com/develop/develop-images/dockerfile_best-practices/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;WORKDIR command&lt;/strong&gt; is used to define the working directory of a Docker container. Any RUN, CMD, ADD, COPY, or ENTRYPOINT command will be executed in the specified working directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;apt vs. apt-get&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apt is a subset of apt-get and apt is usually preferred&lt;/li&gt;
&lt;li&gt;apt provides all the necessary commands for package management so just go with that&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;apt update vs. apt upgrade&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apt update updates the list of available packages and their versions, but it does not install or upgrade any packages.&lt;/li&gt;
&lt;li&gt;apt upgrade actually installs newer versions of the packages you have. After updating the lists&lt;/li&gt;
&lt;li&gt;-y flag means "say yes to all"&lt;/li&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/questions/94102/what-is-the-difference-between-apt-get-update-and-upgrade"&gt;https://askubuntu.com/questions/94102/what-is-the-difference-between-apt-get-update-and-upgrade&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;--C++ basics--&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generics in C++&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#include &amp;lt;iostream&amp;gt;

using namespace std;

template &amp;lt;class T&amp;gt;

T GetMax (T a, T b) {

T result;

result = (a&amp;gt;b)? a : b;

return (result);

}

int main () {

int i=5, j=6, k;

long l=10, m=5, n;

k=GetMax&amp;lt;int&amp;gt;(i,j);

n=GetMax&amp;lt;long&amp;gt;(l,m);

cout &amp;lt;&amp;lt; k &amp;lt;&amp;lt; endl;

cout &amp;lt;&amp;lt; n &amp;lt;&amp;lt; endl;

return 0;

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Templates in C++: &lt;a href="https://www.cplusplus.com/doc/oldtutorial/templates/"&gt;https://www.cplusplus.com/doc/oldtutorial/templates/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logical data structures—implemented using physical data structures: arrays or linked lists&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stack (linear, LIFO)&lt;/li&gt;
&lt;li&gt;Queues (linear, FIFO)&lt;/li&gt;
&lt;li&gt;Trees (non-linear)&lt;/li&gt;
&lt;li&gt;Graph (non-linear)&lt;/li&gt;
&lt;li&gt;Hash Table (tabular)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Abstract Data Type (ADT)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ADT is a type (or class) for objects whose behavior is defined by a set of value and a set of operations&lt;/li&gt;
&lt;li&gt;The definition of ADT only describes what operations are to be performed but not how these operations will be implemented, making it abstract&lt;/li&gt;
&lt;li&gt;List, Stack, &amp;amp; Queue ADTs: &lt;a href="https://www.geeksforgeeks.org/abstract-data-types/"&gt;https://www.geeksforgeeks.org/abstract-data-types/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;--Discrete Math--&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Math Theorem Example: an even integer plus an odd integer is another odd integer&lt;/p&gt;

&lt;p&gt;Proof:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suppose m is even and n is odd (1. State the assumptions)&lt;/li&gt;
&lt;li&gt;∃k1 ∈ Z and ∃k2 ∈ Z so that m = 2k1 and n=2k2 + 1 (2. Formally define the assumptions)&lt;/li&gt;
&lt;li&gt;Then, m + n = (2k1) + (2k2+1) = 2(k1+k2) + 1. Let k3 = k1 + k2, and note it is an integer. (3. Manipulation)&lt;/li&gt;
&lt;li&gt;Hence ∃k3 ∈ Z so that m + n = 2k3 + 1 (4. Arrive at definition of conclusion)&lt;/li&gt;
&lt;li&gt;Thus m + n is odd (5. Conclusion)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Divisibility&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For n and d integers, d ≠ 0, d | n ↔  if ∃k ∈ Z such that n = dk&lt;/li&gt;
&lt;li&gt;When we say d | n, it means n is divisible by d&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;∀x ∈ D, P(x) → Q(x) where we quantify with specific x values, it uses a single arrow to show implication between two statements&lt;/p&gt;

&lt;p&gt;P(x) ⇒ Q(x) with a double arrow is an implication between two predicates; it means the same thing as above&lt;/p&gt;

&lt;p&gt;Other Proof Methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disproving with Counterexamples&lt;/li&gt;
&lt;li&gt;Proof by division into cases&lt;/li&gt;
&lt;li&gt;Proof by contradiction&lt;/li&gt;
&lt;li&gt;Proof by contrapositive&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/25 TIL: C++ basics (heap memory, referencing, pointer to struct)</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Wed, 26 May 2021 03:01:13 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-25-til-c-basics-heap-memory-referencing-pointer-to-struct-1edo</link>
      <guid>https://dev.to/davidhwangij/5-25-til-c-basics-heap-memory-referencing-pointer-to-struct-1edo</guid>
      <description>&lt;p&gt;&lt;strong&gt;Heap Memory in C&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The heap is a large pool of memory that can be used dynamically - it is also known as the 'free store'. This is memory that is not automatically managed and you have to explicitly allocate &amp;amp; deallocate. It is where global variables are stored and you have whats called 'memory leak' if you fail to free/deallocate the memory.&lt;/li&gt;
&lt;li&gt;To assign memory in heap, we use malloc()&lt;/li&gt;
&lt;li&gt;You must delete (release/de-allocate) the memory in whenever you are dynamically allocating memory Ex) free(p) in C and delete [] p in C++ where p is an array
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// allocates 20 bytes (5 * 4) of heap memory holding an int and assign that pointer to p

p = (int *)malloc(5 * sizeof(int));

free(p);

// C++

p = new int[5];

delete [] p;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Every pointer takes 8 bytes of memory regardless of its data type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Referencing in C++ (only C++)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nickname/alias given to a variable
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
int a = 10;

int &amp;amp;r = a;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Reference has to be initialized (it cannot just be declared)&lt;/li&gt;
&lt;li&gt;Now the variable a is also "called" r (this is not related to pointer)&lt;/li&gt;
&lt;li&gt;Useful in parameter passing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ex)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// instead of having to pass pointers 

void swap(int *x, int *y) { ... }

int main() {

int a = 10; b = 20;

swap(&amp;amp;a, &amp;amp;b);

}

// we can use referencing; now we don't have to pass the pointers

void swap(int &amp;amp;x, int &amp;amp;y) { ... }

int main() {

int a = 10; b = 20;

swap(a, b);

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pointer to Struct&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
struct userInfo u={'david', 25};

struct userInfo *p = &amp;amp;u;

// this won't work bc the dot takes precedence

*p.name = 'davidd';

// instead wrap p inside brackets

(*p).name = 'davidd';

// OR

p → name = 'davidd';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create an object dynamically in heap using pointer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// malloc returns a void pointer; so we typecast it 

p = (struct userInfo*) malloc(sizeof(struct userInfo));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Array as Parameter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrays can only be passed by address; it cannot be passed by value at all (both C &amp;amp; C++)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// when we receive an array with square brackets, it can only be a pointer to the array 

void funcOne(int A[]) { ... }

// for this we have a pointer to an integer; it can point to any integer and even the array

void funcOne(int *A) { ... }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>5/24 TIL: Predicates, Quantifiers</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Tue, 25 May 2021 04:23:14 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-24-til-predicates-quantifiers-de8</link>
      <guid>https://dev.to/davidhwangij/5-24-til-predicates-quantifiers-de8</guid>
      <description>&lt;p&gt;Predicates&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A statement is either TRUE or false. But x &amp;gt; 5 is not a statement until we have the value determined for x.&lt;/li&gt;
&lt;li&gt;A predicate is a sentence depending on variables which becomes a statement upon substituting values in the domain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Truth Set of a predicate P(x):&lt;/p&gt;

&lt;p&gt;{ x ∈ D | P(x) }&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shows which of the elements in the domain make the predicate true&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Universal Quantifier ∀&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"for all" (every)&lt;/li&gt;
&lt;li&gt;main use: "quantifying" predicates&lt;/li&gt;
&lt;li&gt;∀x ∈ D, P(x) — for all x in the domain, P(x) is true&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existential Quantifier ∃&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"there exists" (some)&lt;/li&gt;
&lt;li&gt;∃x ∈ D, P(x) — there exists x in the domain, such that P(x) is true&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Universal/existential quantifiers turn predicates back into a statement&lt;/p&gt;

&lt;p&gt;Negating a universal&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~(∀x ∈ D, P(x)) ≡ ∃x ∈ D, ~P(x)&lt;/li&gt;
&lt;li&gt;meaning: if it's not the case that for all values some properties are true, there is at least one value where the property is false&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Negating logical statements with multiple quantifiers&lt;/p&gt;

&lt;p&gt;∀x ∈ D, P(x)) ≡ ∃&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ex) "Every integer has a larger integer"&lt;/li&gt;
&lt;li&gt;∀x ∈ Z, P(x) → ∀x ∈ Z, ∃y ∈ Z, y &amp;gt; x -negate→ ∃x ∈ Z, ∀y ∈ Z, y ≤ x&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>5/23 TIL: Go Signals, http, &amp; Linux file systems</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Mon, 24 May 2021 02:43:36 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-23-til-531f</link>
      <guid>https://dev.to/davidhwangij/5-23-til-531f</guid>
      <description>&lt;p&gt;&lt;strong&gt;--Golang--&lt;/strong&gt;&lt;br&gt;
Go flag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
addr = flag.String("addr", "0.0.0.0:9090", "Default HTTP address")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;port 9090 will be the default value unless the user specifies the port on the command line by doing something like --addr 0.0.0.0:8080.&lt;/li&gt;
&lt;li&gt;the first parameter is the name of the flag, the second parameter the default value, and the last parameter describes the default value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Package http&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
s := &amp;amp;http.Server{

Addr:           ":8080",

Handler:        myHandler,

ReadTimeout:    10 * time.Second,

WriteTimeout:   10 * time.Second,

MaxHeaderBytes: 1 &amp;lt;&amp;lt; 20,

}

s.ListenAndServe()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://golang.org/pkg/net/http/#Handler"&gt;https://golang.org/pkg/net/http/#Handler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go Signals&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sigChan := make(chan os.Signal)

// relays incoming signals to sigChan

signal.Notify(sigChan, os.Interrupt, os.Kill)

sig := ← sigChan

log.Println("Received terminate signal, gracefully shutting down", sig)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;--Systems--&lt;/strong&gt;&lt;br&gt;
File Systems&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Devices are represented by entries in the /dev directories&lt;/li&gt;
&lt;li&gt;Each device has a corresponding device driver which implements a standard set of operations: open, read, write, close functions that were discussed in file IO topic&lt;/li&gt;
&lt;li&gt;A device may have a corresponding hardware device driver that implements an API&lt;/li&gt;
&lt;li&gt;A hard disk is divided into one or more partitions, each of which may contain a file system&lt;/li&gt;
&lt;li&gt;A file system is an organized collection of regular files and directories&lt;/li&gt;
&lt;li&gt;Linux implements file systems such as the ext2 file system&lt;/li&gt;
&lt;li&gt;All the file systems in Linux are mounted under a single directory tree with a directory / at its root; a privileged process can mount and unmount a file system using mount() and unmount()&lt;/li&gt;
&lt;li&gt;Information about the mounted file systems can be retrieved using statvfs()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;--Discrete Math--&lt;/strong&gt;&lt;br&gt;
Modus Ponens&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A valid argument is a list of premises from which the conclusion follows&lt;/li&gt;
&lt;li&gt;Ex) if p, then q. p. Therefore, q.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modus Tollens&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If p, then q. ~q. Therefore, ~p.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logical Arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generalization: p. Therefore, p V q. (always true)&lt;/li&gt;
&lt;li&gt;Specialization: p ʌ q. Therefore, p.&lt;/li&gt;
&lt;li&gt;Contradiction: ~p → c. Therefore, p.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>5/22 TIL: Processes, Contrapositive, etc.</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Sun, 23 May 2021 02:55:21 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-22-til-1m4b</link>
      <guid>https://dev.to/davidhwangij/5-22-til-1m4b</guid>
      <description>&lt;p&gt;&lt;strong&gt;--Systems--&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Processes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A process is an instance of an executing program; each process has a unique process id &amp;amp; its parent process id&lt;/li&gt;
&lt;li&gt;Virtual memory of a process is logically divided into:

&lt;ul&gt;
&lt;li&gt;Text initialized &amp;amp; uninitialized&lt;/li&gt;
&lt;li&gt;Data&lt;/li&gt;
&lt;li&gt;Stack - a series of frames with a new frame being added as a function is invoked &amp;amp; removed when the function returns; each frame contains local variables, function arguments, and called linkage information for a single function implication&lt;/li&gt;
&lt;li&gt;Heap&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Command line arguments supplied when a program is invoked are made available via argc and argv arguments to the main function
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#include&amp;lt;unistd.h&amp;gt;

int proc_id = getpid();

int par_proc_id = getppid();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Memory Allocation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
malloc() // memory allocation

calloc() // contiguous allocation

free() // de-allocate

realloc() // re-allocate

// example

int* ptr

int num=8;

ptr = (int*)malloc(num*sizeof(int))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;System Limits&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SUSV3 (Single Unix Specification V3) adds a lot of new functions into C/C++ library&lt;/li&gt;
&lt;li&gt;SUSV3 specifies limits that an implementations may enforce and system options that an implementation may support
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#include &amp;lt;limits.h&amp;gt;

LONG_MIN, LONG_MAX, CHAR_MIN, CHAR_MAX // etc

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;--Discrete Math--&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;if p then q (p → q)&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%2Fuploads%2Farticles%2F5c23ic9t5v6lf45xdlvj.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%2Fuploads%2Farticles%2F5c23ic9t5v6lf45xdlvj.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;p → q ≡ ~p V q&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;~(p → q) ≡ ~(~p V q) ≡ (~~p ʌ ~q) ≡ p ʌ ~q&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apply DeMorgan's Law&lt;/li&gt;
&lt;li&gt;the only scenario where p → q is false is when p is T and q is F. Negating that p → q would be F. So this is equivalent to p ʌ ~q where p is T and q is F.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contrapositive of a conditional&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;p → q ≡ ~q → ~p because&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;p → q ≡ &lt;strong&gt;~p V q&lt;/strong&gt; and&lt;/li&gt;
&lt;li&gt;~q → ~p ≡ &lt;strong&gt;q V ~p&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;with &lt;strong&gt;~p V q&lt;/strong&gt; ≡ &lt;strong&gt;q V ~p&lt;/strong&gt; being true&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Converse: p → q is the statement q → p (not logically equivalent)&lt;/p&gt;

&lt;p&gt;Inverse: p → q is the statement ~p → ~q (contrapositive of a converse)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;conclusion: converse ≡ inverse since contrapositive statements are logically equivalent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Biconditional p ↔  q&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a conjunctive statement where we have both p → q and q → p implications&lt;/li&gt;
&lt;li&gt;"if and only if"&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>5/21 TIL: C/C++ setup on MacOS &amp; C pointers</title>
      <dc:creator>David Hwang</dc:creator>
      <pubDate>Sat, 22 May 2021 03:41:26 +0000</pubDate>
      <link>https://dev.to/davidhwangij/5-21-til-c-c-setup-on-macos-c-pointers-17km</link>
      <guid>https://dev.to/davidhwangij/5-21-til-c-c-setup-on-macos-c-pointers-17km</guid>
      <description>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To run C programs, we need a compiler&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clang and gcc are usually used on MacOS—they are built-in&lt;/li&gt;
&lt;li&gt;we can check if these compilers exist in our system by doing this on terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  gcc -v

  clang -v

&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;if they aren't found, we can install it by running: xcode-select --install&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=f0vVV4NPmjQ"&gt;https://www.youtube.com/watch?v=f0vVV4NPmjQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;To run a C program in VS code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the 'C/C++' and 'code runner' extensions&lt;/li&gt;
&lt;li&gt;Write your C program and compile it by selecting Terminal &amp;gt; Run Build Task (choose gcc/clang build in the dropdown)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Pointers in C&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cs.fsu.edu/~myers/c++/notes/pointers1.html"&gt;https://www.cs.fsu.edu/~myers/c++/notes/pointers1.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;int *p&lt;/code&gt;, &lt;code&gt;int* p&lt;/code&gt; are the same&lt;/li&gt;
&lt;li&gt;asterisk (*) used in the declaration statement is used to define the pointer variable&lt;/li&gt;
&lt;li&gt;asterisk (*) used elsewhere is used to dereference the pointer; for instance:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  int x = 10;

  // * used here in the declaration statement has nothing to do with dereferencing; we are simply declaring a variable named aptr of type 'pointer to int' (meaning it stores the address of an integer variable)

  int *aptr = &amp;amp;x; 

  printf("%x returns a memory address", aptr);

  // * here is now used for dereferencing

  printf("%d is the value dereferenced, *aptr);

&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
