diff --git a/src/content/posts/file-io-in-go.mdx b/src/content/posts/file-io-in-go.mdx index 1b41b57..e2b5476 100755 --- a/src/content/posts/file-io-in-go.mdx +++ b/src/content/posts/file-io-in-go.mdx @@ -9,7 +9,7 @@ tags: ["go"] draft: false --- -# Printing in Golang +## Printing in Golang Go has many ways to print. All printing functions stem from the `fmt` package. @@ -31,14 +31,14 @@ Third family - `fmt.Sprintf ` outputs to a string but also format the string. -# File I/O Packages +## File I/O Packages 1. Os package: has functions to open and create files, list directories etc... and has the `File` type 2. Io package: has utilities to read and write 3. Bufio pakcage: provides buffered i/o scanners etc... 4. Io/ioutil package: has extra utilities such as reading and an entire file to memory, or writing it all out at once 5. Strconv package: has utilities to convert to/from string representations -### Misc commands for files: +## Misc commands for files: - Opening a file: `os.Open(fname)` - Copying from a file to standard output: `io.Copy(os.Stdout, file)` - Reading all the data from a file (without buffering): `ioutil.ReadAll(file)` diff --git a/src/content/posts/why-is-concurrency-hard.mdx b/src/content/posts/why-is-concurrency-hard.mdx index 8f24b11..34ed1a0 100644 --- a/src/content/posts/why-is-concurrency-hard.mdx +++ b/src/content/posts/why-is-concurrency-hard.mdx @@ -13,7 +13,7 @@ Concurrency can be extrememly difficult to get right. Bugs can occur even after Running into concurrency issues is so common that we are now able to label common pitfalls. Below I have listed the most common issues of working with concurrency: -# Race Conditions +## Race Conditions A race condition occurs when two or more processes must execute in a specific order, but the program allows for the operations to occur in any order, or an order that causes an error. A classic example is one concurrent operation trying to read from a variable while (potentially) at the same time another concurrent operation is trying to write to it. ```go showLineNumbers @@ -55,7 +55,7 @@ We have simply made it increasingly unlikely for our program to product the "inc Another technique that might help in detecting race conditions is testing your program in different environments. Data races normally tend to occur when there is a change in an environment that was not thought of like a variation in memory or CPU. -# Atomicity +## Atomicity If series of executions can in it's entirity without interruption in the defined context, then they are considered to be atomic.\ Atomic comes from the greek word Atom. Which means indivisible. Obviously, in modern physics we know this is not true. But it does bring the point across of a process or an execution being indivisible and uninterruptable. @@ -77,7 +77,7 @@ Multiple steps are completed from a simple statement.Each step within the proces Most statements are not atomic. Thus proving another reason why concurrency can be very challenging. -# Memory Access Synchronization +## Memory Access Synchronization There is a difference between a **data race** and a **race condition**. A race condition occurs when the order of executions are nondeterministic. A data race occurs when many sections of the program are trying to access the same data. A need arises to synchroinze memory when there is a data race. @@ -134,7 +134,7 @@ Knowing what data needs to be synchronized and how frequently you need to lock d If all problems of the previous section are addressed then you will never get a wrong output. The following problems are for your program to always be doing work. In other words, the program has something useful to do at all times: -# Deadlock +## Deadlock A deadlock happens when all goroutines are blocked. This can happen when all goroutines are waiting for eachother. In this case, your program will not work without manual intervention. Here is an example of a deadlock: @@ -181,7 +181,7 @@ Deadlocks can be hard to spot. A technique that can help us identify them are th The program above fulfills all of the conditions. Hence the reason for having a deadlock. -# Livelock +## Livelock A very famous example of a livelock would be the following: Imagine you were in a tight corridor. There is just enough space for two people to walk. You come face to face with another person. You move left, the other person moves left as well in an attempt to walk by. You move right, the other person moves right as well. Both people become stuck in this state of hallway shuffle moving left and right continuously! @@ -190,7 +190,7 @@ This occurs when two goroutines or concurrent processes are trying to prevent de Livelock is a subset of a larger problem called starvation. -# Starvation +## Starvation A greedy goroutine means when one goroutine gets in the way of other goroutines. When you have a greedy goroutine, other concurrent processes can't find resources to perform their work. This is an example of starvation. A goroutine can also suffer finding resources from outside the Go program as well. Lack of CPU power, database connection, lack of memory etc.. can all lead to starvation. Starvation is relatively easy to spot when external factors are in play but can be quite difficult to spot when goroutines are competing against eachother. diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 11982da..9e13b70 100755 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -35,7 +35,7 @@ export interface Props { canonical?: string; } -// distructure frontmatters +// destructure frontmatters const { title, meta_title, description, image, noindex, canonical } = Astro.props; --- diff --git a/src/layouts/PostSingle.astro b/src/layouts/PostSingle.astro index fd4eea5..ab7e1a4 100755 --- a/src/layouts/PostSingle.astro +++ b/src/layouts/PostSingle.astro @@ -7,49 +7,31 @@ import dateFormat from "@/lib/utils/dateFormat"; import similerItems from "@/lib/utils/similarItems"; import { humanize, markdownify, slugify } from "@/lib/utils/textConverter"; import { BiCalendarEdit, BiCategoryAlt } from "react-icons/bi"; +import TableOfContents from "./components/TableOfContents.astro"; const allAuthors = await getSinglePage("authors"); const posts = await getSinglePage("posts"); const { post } = Astro.props; +const { headings } = Astro.props; const similarPosts = similerItems(post, posts, post.slug); const { Content } = await post.render(); const { title, description, authors, categories, image, date, tags } = post.data; --- -
-
-
-
-

-
    -
  • - { - allAuthors - .filter((author) => - authors - .map((author: string) => slugify(author)) - .includes(slugify(author.data.title)), - ) - .map((author, i) => ( - - {author.data.image && ( - {author.data.title} - )} - {author.data.title} - - )) - } -
  • +
    +
    +
    +
    +

    +
    • <>{dateFormat(date)} @@ -76,50 +58,66 @@ const { title, description, authors, categories, image, date, tags } =

    - -
    - { - image && ( - {title} - ) - } -
    - -
    -
    - -
    -
    - - +
    + { + image && ( + {title} -
    + ) + } +
    +
    + +
    + + +
    +
    + +
    +
    -
    -

+
+
+ + +
+
@@ -133,3 +131,59 @@ const { title, description, authors, categories, image, date, tags } = ) } + + diff --git a/src/layouts/components/TableOfContents.astro b/src/layouts/components/TableOfContents.astro new file mode 100644 index 0000000..2a0a542 --- /dev/null +++ b/src/layouts/components/TableOfContents.astro @@ -0,0 +1,42 @@ +--- +// TableOfContents.astro +const { headings } = Astro.props; +const toc = buildToc(headings); +import TableOfContentsHeading from "./TableOfContentsHeading.astro"; + +interface Heading { + depth: number; + title: string; + subheadings: Heading[]; +} + +function buildToc(headings: Array<{ depth: number; title: string }>): Heading[] { + const toc: Heading[] = []; + const parentHeadings = new Map(); + + headings.forEach((h) => { + const heading: Heading = { ...h, subheadings: [] }; + parentHeadings.set(heading.depth, heading); + + // Change 2 to 1 if your markdown includes your

+ if (heading.depth === 2) { + toc.push(heading); + } else { + const parentHeading = parentHeadings.get(heading.depth - 1); + if (parentHeading) { + parentHeading.subheadings.push(heading); + } else { + console.warn(`No parent found for heading at depth ${heading.depth}`); + } + } + }); + + return toc; +} +--- + + \ No newline at end of file diff --git a/src/layouts/components/TableOfContentsHeading.astro b/src/layouts/components/TableOfContentsHeading.astro new file mode 100644 index 0000000..f2cc35e --- /dev/null +++ b/src/layouts/components/TableOfContentsHeading.astro @@ -0,0 +1,19 @@ +--- +// TableOfContentsHeading.astro +const { heading } = Astro.props; +--- + +
  • + + {heading.text} + + { + heading.subheadings.length > 0 && ( +
      + {heading.subheadings.map((subheading) => ( + + ))} +
    + ) + } +
  • \ No newline at end of file diff --git a/src/pages/[regular].astro b/src/pages/[regular].astro index 8228608..3743225 100755 --- a/src/pages/[regular].astro +++ b/src/pages/[regular].astro @@ -24,6 +24,7 @@ export async function getStaticPaths() { const { page } = Astro.props; const { title, meta_title, description, image } = page.data; +const { headings } = await page.render() --- { postsSlug.includes(page.slug) ? ( - + ) : ( ) diff --git a/tsconfig.json b/tsconfig.json index 18d9566..c3483d4 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "isolatedModules": true, "incremental": true, "allowSyntheticDefaultImports": true, + "noImplicitAny": false, "paths": { "@/components/*": ["./src/layouts/components/*"], "@/shortcodes/*": ["./src/layouts/shortcodes/*"],