<?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: Emma Ham</title>
    <description>The latest articles on DEV Community by Emma Ham (@ham8821).</description>
    <link>https://dev.to/ham8821</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%2F222237%2Fc48cfe91-2801-4511-9848-d301db693c8b.jpg</url>
      <title>DEV Community: Emma Ham</title>
      <link>https://dev.to/ham8821</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ham8821"/>
    <language>en</language>
    <item>
      <title>I know you want to build AI applications too : LangChain</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Sun, 18 Feb 2024 05:06:37 +0000</pubDate>
      <link>https://dev.to/ham8821/i-know-you-want-to-build-ai-applications-too-langchain-4jn7</link>
      <guid>https://dev.to/ham8821/i-know-you-want-to-build-ai-applications-too-langchain-4jn7</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%2Fuploads%2Farticles%2F1n3eh0ijkyw1s1yg6z83.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%2F1n3eh0ijkyw1s1yg6z83.png" alt="n image- title"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Hey there!
&lt;/h2&gt;

&lt;p&gt;How have you been?&lt;/p&gt;

&lt;p&gt;After posting about &lt;a href="https://dev.to/ham8821/you-are-using-chatgpt-incorrectly-12ii"&gt;ChatGPT prompt patterns &lt;/a&gt; and seeing your incredible responses, &lt;br&gt;
it's clear to me that our interest isn't just in using AI tools like ChatGPT. &lt;br&gt;
We're also keen on figuring out how we can use ai technologies like LLMs(Large Language Model) to build ai powered applications. &lt;br&gt;
If that sounds like you, then you came to the right place🚀🚀!&lt;/p&gt;

&lt;p&gt;Because today, what we I will be looking at together might be exactly what you've been looking for and a game changer!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;So, Let's see what's on the menu today!&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%2Fuploads%2Farticles%2Flpgzi879vpce7ywe3img.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%2Flpgzi879vpce7ywe3img.png" alt="LangChain image- main"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The core idea of this post is to introduce "LangChain" as a tool to crafting applications powered by large language models (LLMs) at a high level.&lt;/p&gt;

&lt;p&gt;We'll begin by unpacking the essence of LangChain—the 'what' and 'why' that define its core. We’ll delve a little into its inner workings and uncover the advantages it offers.&lt;/p&gt;

&lt;p&gt;And then we will briefly look into the main components of LangChain, exploring what LangChain is made of and what makes it work the way it does.&lt;/p&gt;

&lt;p&gt;What &lt;u&gt;won't be included&lt;/u&gt; in this particular post are detailed implementation guide and demo projects which I will be writing as part of a next post:) &lt;/p&gt;

&lt;h2&gt;
  
  
  - But first,
&lt;/h2&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%2Fuploads%2Farticles%2F8hrdxjut5zt97y6n62r6.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%2F8hrdxjut5zt97y6n62r6.png" alt="LangChain image- Table of content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But hold on a second, let me just put this out there. &lt;br&gt;
I am not an AI expert nor a ML engineer, actually I am far from it. &lt;br&gt;
Therefore, I obviously don’t know what I am talking about, what a disappointment😞😞😞&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But you know that’s also exactly why I chose this topic for today’s post.&lt;/strong&gt; Because  I’ve always been a passionate user of these llm tools like ChatGPT, Bards but the idea of building something with it always felt like a huge project that was too intimidating for me to even try.&lt;/p&gt;

&lt;p&gt;And I thought &lt;br&gt;
"There’s gotta be an easier way to do this👿"&lt;/p&gt;

&lt;p&gt;And since I’ve discovered LangChain few weeks ago, it was such an interesting learning journey. And more than anything I wanted to share this experience with you guys so I hope you guys find something useful from this article!&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What is LangChain, anyway?
&lt;/h2&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%2Fuploads%2Farticles%2Ftau36rn3ebu7wcaq95rl.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%2Ftau36rn3ebu7wcaq95rl.png" alt="1. What is LangChain, anyway"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at the official documentation, LangChain is introduced as a framework designed to simplify the process of building llm powered application. &lt;/p&gt;

&lt;p&gt;So, it's not a kind of LLM or an AI chatbot itself. &lt;strong&gt;Instead, it's more like a support layer that stands between us and the LLMs, making it easier for us to work with LLMs and get better results.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are two things that make LangChain special.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, It's data-aware.&lt;/strong&gt; &lt;br&gt;
This means you can feed your own data into large language models (LLMs). Instead of relying solely on the information they were trained with, you can link these models to your own data to get responses that are specifically &lt;strong&gt;meaningful to you&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second standout feature is something called "Agents".&lt;/strong&gt; &lt;br&gt;
Agents elevate the application beyond simply responding to questions like a chatbot. They add the ability to perform actions on our behalf. Whether it's sending an email, updating a database, or buying products online, the potential uses are both endless and incredibly powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Basic data flow of LangChain
&lt;/h2&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%2Fuploads%2Farticles%2Fotxfohzbenwbabf4udyv.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%2Fotxfohzbenwbabf4udyv.png" alt="Basic data flow of LangChain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The basic flow goes something like this: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;1. Question&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
We start by asking a question to an LLM. &lt;br&gt;
By this point, we've already loaded our data into LangChain, which could be stored in a Vectorstore. Then, based on the question asked, &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;2. Similarity/Vector search&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
It carry out a similarity search to pull out the relevant information.&lt;br&gt;
This step is crucial for enabling the LLMs to give better responses, as this relevant info is passed as context for llm.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;3. Crafting an answer&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
When the LLM gets the question along with this background information, it crafts an answer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;4. Actions&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
. Depending on our needs, we can then let the model to take a set of actions based on this process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some use cases&lt;/strong&gt;&lt;br&gt;
Use cases can be various but some of really common uses case could be SQL QA which we can ask a question about the data in a SQL database and get back a natural language answer. Or QA about Documents, SummarisationsAI, chatbots analysing data and so on.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. But still, why use it?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;But “Why” LangChain though?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It sounds like we can achieve this using LLM directly without any additional helper. &lt;/p&gt;

&lt;p&gt;True, but I also believe that LangChain, like any new technology, was introduced to solve certain challenges that current large language models face.&lt;/p&gt;

&lt;p&gt;And for that let’s take ChatGPT for example to understand why something like LangChain might be helpful.&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%2Fuploads%2Farticles%2F7eqejze2umsosqa42lws.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%2F7eqejze2umsosqa42lws.png" alt="But why use it 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Limitation of real-time data access&lt;/strong&gt;&lt;br&gt;
GPT models, such as GPT-3.5, which many of us use, are limited by the information they were trained on, with the latest update being in January 2022. The newer version of GPT includes content up to April 2023, offering slightly more up-to-date information, but it comes with a subscription cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Token Limitation&lt;/strong&gt;&lt;br&gt;
This means there's a maximum number of tokens (pieces of text) that the model can handle in a single question and its response. This limitation can impact the model's understanding of questions and its ability to generate meaningful answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Hallucination&lt;/strong&gt;&lt;br&gt;
"Hallucination" in AI is also an issue. A Purdue University study last year found that when ChatGPT was tested with 517 Stack Overflow programming questions, it returned inaccurate or broken code in over half the cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typical Approaches&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%2Fuploads%2Farticles%2Fcsti69f6k91ssfkyrwg6.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%2Fcsti69f6k91ssfkyrwg6.png" alt="Typical solutions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In machine learning development, when issues like these happen, it can be approached through fine-tuning, N-shot learning, and in-context learning.&lt;/p&gt;

&lt;p&gt;Fine-tuning tweaks a model's parameters to better perform specific tasks. N-shot learning leverages a few examples to refine the model's task-specific responses. &lt;strong&gt;In contrast&lt;/strong&gt;, in-context learning embeds the necessary information within the prompt itself, &lt;strong&gt;bypassing additional training—this can be more efficient than fine-tuning, which requires direct model adjustments and can be resource-intensive.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangChain is designed to facilitate in-context learning effectively.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Coming back to limitations&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%2Fuploads%2Farticles%2Fm62v4yg3ucziqrt2xd1l.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%2Fm62v4yg3ucziqrt2xd1l.png" alt="limitations2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LangChain offers some smart solutions to tackle these issues:&lt;/p&gt;

&lt;p&gt;For accessing information, you can use &lt;strong&gt;your own data or a search agent&lt;/strong&gt; (like a Google search agent) with LangChain to do real-time searches.&lt;/p&gt;

&lt;p&gt;For Token limitation, LangChain provides &lt;strong&gt;TextSplitters&lt;/strong&gt; and its parameters to split the big chunk of information into smaller Chungs in a cleaver way helping maintain the performance of LLMs.&lt;/p&gt;

&lt;p&gt;For Hallucination, LangChain has effective methods to &lt;strong&gt;shape prompts&lt;/strong&gt; depending on the model type and includes built-in instructions to minimise errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What else?&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%2Fuploads%2Farticles%2Foynyjzht9yydjezbhp7q.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%2Foynyjzht9yydjezbhp7q.png" alt="Other reasons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quite recently we will all remember this drama around this guy in OpenAI, &lt;br&gt;
Like there was no there time quite like now where everything is changing so quickly, that sometimes can worries us whether we will always need to be alerted when we use things like LLM models because we just don’t know what’s gonna happen!  &lt;/p&gt;

&lt;p&gt;One of my favourite part of LangChain is that is just &lt;strong&gt;unbelievably easy to migrate from one llm model to another.&lt;/strong&gt; It literally takes just few lines of code changes because whatever happens behind the scenes, it is all handled by LangChain!&lt;/p&gt;

&lt;p&gt;How cool is this? On the top of it, LangChain are supported by some helpful tools like LangSmith which you can see in this small screenshot that it is quite helpful when debugging the application, if you want to know what was passed as prompt and how the whole process played out.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. 6 Main Components of LangChain
&lt;/h2&gt;

&lt;p&gt;So far, we looked at how long chain work from a high level, Now let’s take a look at these 6 main components of LangChain that make this work. &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%2Fuploads%2Farticles%2Fuwkco4rjniz8ijye4xoa.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%2Fuwkco4rjniz8ijye4xoa.png" alt="Main Components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 LLM : An engine of LangChain&lt;/em&gt;&lt;br&gt;
here are plenty of models that LangChain can integrate for us including GPT models, palm, gemini, open source models like Llama etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 Prompt:  A command to LLM&lt;/em&gt;&lt;br&gt;
I've been saying "question" up until now for the convenience sake, but essentially, a prompt is a command we give to an LLM to get the output we want. This can be a question, some instructions, or context we provide.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 Indexing: Organising the data for LLM&lt;/em&gt;&lt;br&gt;
Indexing is about organising and structuring our data so the LLM can work with it effectively. &lt;br&gt;
We touched on text splitters before, but there are also document loaders, vectorstores, and much more!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 Memory: What makes a conversation?&lt;/em&gt;&lt;br&gt;
Many LLM applications will have a conversational interface. An essential component of a conversation is being able to refer to information introduced earlier in the conversation. LangChain provides utilities for adding memory to a system. &lt;/p&gt;

&lt;p&gt;For example,&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%2Fmwsiswtbcd3xsxa5skzl.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%2Fmwsiswtbcd3xsxa5skzl.png" alt="Memory types"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 Chain : Chaining complex operations into a single line!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is probably the most important concept because even the LangChain is named after this component! &lt;/p&gt;

&lt;p&gt;In LangChain, &lt;strong&gt;a 'chain' links a series of operations together.&lt;/strong&gt; Each operation's output is directly fed into the next as its input. This sequence continues from one operation to the next until the final result is produced.&lt;/p&gt;

&lt;p&gt;Chain is a unique component that makes complicated data flow from us to llm more straight forward.&lt;/p&gt;

&lt;p&gt;Here is a very simple example of chain&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chain = prompt | llm | OutputParser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you notice &lt;strong&gt;"|"&lt;/strong&gt; is a chain expression which binds operations into a single liner. &lt;br&gt;
As explained above, each operation's output will be input for the next operation.&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%2Fuploads%2Farticles%2F5ixhckjgyyej2bsalwe6.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%2F5ixhckjgyyej2bsalwe6.png" alt="chain flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a very simple example but still explains core concept of chain.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- 💡 Agents : Let it action for you!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The core idea of agents is making language model to select actions to execute.&lt;br&gt;
It is not like we are making it to perform certain actions, but rather is letting the model to use its &lt;strong&gt;own reasoning skills&lt;/strong&gt; to decide on the correct action to take.&lt;/p&gt;

&lt;p&gt;It sounds like a magic but if you take a look at this simple code snippet, It is not so much of a magic actually. &lt;/p&gt;

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

agent = initialise_agent(
   llm=llm,
    verbose=True,
    agent=AgentType,
    tools=[
        StructuredTool.from_function(
            func=plus,
            name="Sum Calculator",
            description="Use this to perform sums of two numbers. This tool take two arguments, both should be numbers.",
        )
    ],
 )
 agent.invoke(prompt)


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

&lt;/div&gt;

&lt;p&gt;Take a look at the "tools=", we are sending &lt;strong&gt;a list of tools&lt;/strong&gt; when we are initialising agent. &lt;br&gt;
In the example above, we seem to send a tool called "plus" saying LLM to use this tool when "perform sums of two numbers". &lt;/p&gt;

&lt;p&gt;When we invoke this agent like this&lt;/p&gt;

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

agent.invoke(
"Give me sum of 3,32,4234,32543534,43,1,0,123,344,12,11,5,78,03,12."
)


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

&lt;/div&gt;

&lt;p&gt;LLM will evaluate this command and choose to use the provided tool when performing sum operations. &lt;/p&gt;

&lt;p&gt;We are enabling LLM to use its reasoning skill in deciding what to do to return desired output by LangChain component called "Agent" here.&lt;/p&gt;

&lt;p&gt;In real world scenarios, This could be sending an email, updating database, requesting network call or purchasing products online and many more using Agents! &lt;br&gt;
Very Powerful isn't it?👏👏👏&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Example DocsAssistantAI
&lt;/h2&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%2Fuploads%2Farticles%2Fsdcu2j8tv3ojd25m0of0.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%2Fsdcu2j8tv3ojd25m0of0.png" alt="DocsAssistantAI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's imagine DocsAssistAI uses LangChain to analyze documents for us:&lt;/p&gt;

&lt;p&gt;a. We start by uploading any document, whether it's a calendar event, an email, an article, or a sales report.&lt;/p&gt;

&lt;p&gt;b. Next, we break down the document into smaller sections to help the LLM process the information more efficiently.&lt;/p&gt;

&lt;p&gt;c. These pieces are then converted into vectors—a format the LLM can understand.&lt;/p&gt;

&lt;p&gt;d. When we ask a question, the system searches for and provides relevant context to the LLM, along with the query and chat history.&lt;/p&gt;

&lt;p&gt;e. The LLM then gives us an answer.&lt;/p&gt;

&lt;p&gt;For example during "Retrieving our data and send relevant data extracted to llm" part, &lt;/p&gt;

&lt;p&gt;While this is a simplified view, LangChain allows for much more. For instance, in retrieving data, we can refine how we present information to the LLM to optimize the interaction.&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%2Fuploads%2Farticles%2F3uqwm3pgeb63bdps8t58.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%2F3uqwm3pgeb63bdps8t58.png" alt="RAG types"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. What's coming next?
&lt;/h2&gt;

&lt;p&gt;In today's article, we've explored the world of "LangChain" - covering its essence, benefits, functionality, and providing an illustrative example to spark your imagination.&lt;/p&gt;

&lt;p&gt;We intentionally skipped the technical deep dive, such as setting up an OpenAI API key, downloading LangChain, and integrating it with an LLM model, among other details. This more intricate exploration is reserved for a future post, should you be keen on a step-by-step implementation guide.&lt;/p&gt;

&lt;p&gt;I hope this introduction has illuminated the path for your next development venture with LangChain. For those eager to delve further, here are some insightful articles to guide your upcoming projects!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.langchain.com/" rel="noopener noreferrer"&gt;LangChain Official Document&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=aywZrzNaKjs" rel="noopener noreferrer"&gt;LangChain Concepts Tutorial on YouTube&lt;/a&gt;&lt;br&gt;
&lt;a href="https://shishirsingh66g.medium.com/langchain-concepts-part-5-indexes-3d0cc9a15402" rel="noopener noreferrer"&gt;Medium article serious of each components&lt;/a&gt;&lt;br&gt;
&lt;a href="https://deci.ai/blog/retrieval-augmented-generation-using-langchain/" rel="noopener noreferrer"&gt;Retrieval Augmented Generation (RAG) Using LangChain&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/international-school-of-ai-data-science/implementing-rag-with-langchain-and-hugging-face-28e3ea66c5f7" rel="noopener noreferrer"&gt;Implementing RAG with Langchain and Hugging Face&lt;/a&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%2Fuploads%2Farticles%2F6acp6uqqm8g8s3wb0wbz.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%2F6acp6uqqm8g8s3wb0wbz.png" alt="Wrap!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀🚀🚀🚀🚀🚀🚀&lt;br&gt;
&lt;strong&gt;That's a wrap!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you've enjoyed diving into the world of LangChain as much as I did when I first stumbled upon it. Whether you're an AI engineer or not, we're all part of a world brimming with exciting and interesting discoveries every single day.&lt;/p&gt;

&lt;p&gt;I'm eager to hear about your latest interests in AI development. What's been capturing your attention lately? Share your thoughts here, and let's foster a vibrant discussion. Also, stay tuned for our next post, where we'll delve deeper into LangChain with more exciting insights and information. Let's keep the conversation going!&lt;/p&gt;

&lt;p&gt;🚀🚀🚀🚀🚀🚀🚀&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>llm</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>You Are Using ChatGPT Incorrectly!</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Thu, 09 Nov 2023 22:06:52 +0000</pubDate>
      <link>https://dev.to/ham8821/you-are-using-chatgpt-incorrectly-12ii</link>
      <guid>https://dev.to/ham8821/you-are-using-chatgpt-incorrectly-12ii</guid>
      <description>&lt;p&gt;What an accusation! Boo! &lt;br&gt;
I know it might seem a bit strong for a blog post title, but let me explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  In my defense😅
&lt;/h2&gt;

&lt;p&gt;I've encountered this question at one of the recent tech conferences I attended, where an audience member asked the panel speaker, &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Will ChatGPT replace our jobs?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As common as this question has become in the era of AI technology, I was quite impressed with the speaker's response that day. &lt;br&gt;
The individual stated, &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"No, we won't necessarily lose our jobs to ChatGPT, but we might lose them to someone who knows how to use ChatGPT better."&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Ding! This made me question whether I've been utilising ChatGPT to its full potential effectively. &lt;/p&gt;

&lt;p&gt;So today, I'm here to admit that I've been underutilising ChatGPT and to introduce some ways to use it more effectively, which I'll share with you.&lt;/p&gt;

&lt;p&gt;In this post, we will delve into how to make the best use of ChatGPT and other AI-powered generative models as engineers in our daily lives. &lt;br&gt;
To achieve this, &lt;strong&gt;we'll explore some of the most popular and useful prompt patterns that developers can employ.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay tuned!&lt;/strong&gt;&lt;br&gt;
Some of these may be techniques you're already using without realising, or ones you can take advantage of in the future.&lt;/p&gt;

&lt;p&gt;But first, &lt;br&gt;
let's take a moment to consider an interesting research finding from Purdue University. &lt;/p&gt;

&lt;h2&gt;
  
  
  An interesting research
&lt;/h2&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%2Fuploads%2Farticles%2Ftddc12x6hj8az76shne1.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%2Ftddc12x6hj8az76shne1.png" alt="Research"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;According to a recent study conducted by Purdue University, when ChatGPT was presented with around 517 programming questions from Stack Overflow, &lt;strong&gt;it provided answers with inaccuracies or non-functional code 52% of the time.&lt;/strong&gt; The study also revealed that ChatGPT's performance in terms of correctness, comprehensiveness, consistency, and usefulness lags behind that of Stack Overflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7qdqvew93d0fw5qw42x.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%2Fa7qdqvew93d0fw5qw42x.png" alt="hollucinate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, many of us have likely experienced instances of AI "&lt;strong&gt;hallucinating&lt;/strong&gt;," where it produces convincing but incorrect answers. &lt;br&gt;
This leads us to believe that we have the power to validate AI-provided answers. &lt;br&gt;
To do so effectively, &lt;br&gt;
&lt;strong&gt;We need to know how to ask the right questions and frame them properly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After reading this article, I wasn't surprised at all because my ChatGPT has been apologising a lot for providing incorrect answers when I've called it out, which can be quite amusing.😂&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%2Fuploads%2Farticles%2Fsxorsnskrrd4sqdqntcz.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%2Fsxorsnskrrd4sqdqntcz.png" alt="ChatGPT apology screenshot"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4 Prompt Patterns for today&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Setting jokes aside, let's now dive into four prompt patterns that can help make ChatGPT's responses more meaningful, accurate, and aligned with the intent of our questions. Let's start with some standard patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Pattern 1
&lt;/h3&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%2Fuploads%2Farticles%2Fawl7ufo4xnez4ncb4coq.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%2Fawl7ufo4xnez4ncb4coq.png" alt="Persona"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First up is the "&lt;strong&gt;Persona Pattern&lt;/strong&gt;". Using this pattern, we can guide ChatGPT to produce responses tailored to &lt;strong&gt;a specific viewpoint or perspective&lt;/strong&gt;. This is particularly useful for code reviews, architectural advice, tech discussions, and ideas commonly required in our professional field.&lt;/p&gt;




&lt;h3&gt;
  
  
  👉 Pattern 2
&lt;/h3&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%2Fuploads%2Farticles%2Fwghlc1u7qmtz37amyy2v.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%2Fwghlc1u7qmtz37amyy2v.png" alt="2Recipe"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next is the "&lt;strong&gt;Recipe Pattern&lt;/strong&gt;". As the name suggests, this pattern provides step-by-step guidelines based on the question, making it ideal for situations where you have a general idea of what you want to achieve but need detailed instructions.&lt;/p&gt;

&lt;p&gt;For instance, a question like, &lt;em&gt;"Can you provide me with a step-by-step guide for releasing a mobile app to production, including the necessary steps for submitting it to the store for review?"&lt;/em&gt; would be an excellent use case for this pattern.&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%2Fuploads%2Farticles%2Fhxe072gs8ywpeqs3ly2l.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%2Fhxe072gs8ywpeqs3ly2l.png" alt="Example answer"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  👉 Pattern 3
&lt;/h3&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%2Fuploads%2Farticles%2Fshriorqfzgmhjmzglvh4.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%2Fshriorqfzgmhjmzglvh4.png" alt="3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;"Reflection Pattern"&lt;/strong&gt; is the third pattern, and I consider it one of &lt;strong&gt;the most important patterns&lt;/strong&gt; for daily use as a developer. It commands the AI to provide answers with clear reasoning, making it invaluable for spotting instances of AI "hallucination" and validating responses.&lt;/p&gt;

&lt;p&gt;This pattern becomes essential as we increasingly rely on AI in our daily work, potentially leading us to lose our grasp of the truth and its meaning.&lt;/p&gt;

&lt;p&gt;So highly recommend, &lt;br&gt;
Use this pattern &lt;strong&gt;and then start asking questions&lt;/strong&gt;!&lt;/p&gt;




&lt;h3&gt;
  
  
  👉 Pattern 4
&lt;/h3&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%2Fuploads%2Farticles%2Fc4s0g172ttuxfm2swgze.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%2Fc4s0g172ttuxfm2swgze.png" alt="4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, &lt;strong&gt;my all time favourite&lt;/strong&gt;, we have the "&lt;strong&gt;Flip Interaction&lt;/strong&gt;" Pattern. &lt;/p&gt;

&lt;p&gt;This pattern is all about letting &lt;strong&gt;AI take control of the conversation&lt;/strong&gt;, a creative approach when you know what you want to achieve but aren't sure what information ChatGPT needs from you. &lt;br&gt;
In this scenario, the AI inverts roles with you, asking questions for you to answer. It's an exciting way to explore a topic.&lt;/p&gt;

&lt;p&gt;With this pattern, you won't need to worry about asking the right questions; &lt;strong&gt;ChatGPT will guide you by asking the questions it needs answers to in order to address your original query correctly.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀🚀 That wraps up today!🚀🚀
&lt;/h2&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%2Fuploads%2Farticles%2F5glvbr4hzf6u2mmh51en.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%2Fuploads%2Farticles%2F5glvbr4hzf6u2mmh51en.jpg" alt="Last"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In today's developer landscape, it's increasingly likely that we'll turn to AI tools like ChatGPT or Bard in our daily work. AI technologies have made tremendous strides and have a significant impact on both our personal and professional lives. &lt;strong&gt;We are in a world where it's crucial to equip ourselves with the right skills and a deep understanding of what we have at our disposal to make the most of it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope this post helps you feel more confident in using ChatGPT effectively in the future, and I'm open to creating more AI-related posts if there's interest. Thank you!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>generative</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Multi-Modules Architecture: Dependency Management _ Build your own gradle plugin</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Wed, 08 Nov 2023 07:53:27 +0000</pubDate>
      <link>https://dev.to/ham8821/multi-modules-architecture-dependency-management-build-your-own-gradle-plugin-1p1g</link>
      <guid>https://dev.to/ham8821/multi-modules-architecture-dependency-management-build-your-own-gradle-plugin-1p1g</guid>
      <description>&lt;p&gt;Hey fellow devs! &lt;/p&gt;

&lt;p&gt;Today, I've come here to talk about my frustrations that I've got to develop over the past few years in working in multi-module projects with&lt;br&gt;
&lt;strong&gt;Dependency management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And how I managed to make them a bit less, well, head-scratching.💻😅&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%2Fuploads%2Farticles%2F10xexhc46ss71cc6tw7l.jpeg" 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%2F10xexhc46ss71cc6tw7l.jpeg" alt="android"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1: Understanding Multi-Module Projects&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So, what's a multi-module project? As your codebase grows, it becomes harder to manage, resembling a monolithic structure. Multi-modularization comes to the rescue, making your app more modular, scalable, and maintainable.&lt;/p&gt;

&lt;p&gt;The rise of on-demand delivery apps has fueled the popularity of modular codebases, solving common development problems. In this type of project, you'll see multiple separate modules, such as UI, data, and feature modules like login, signup, and dashboard.&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%2Fuploads%2Farticles%2Fgt19d74isa3bbgpy8xbb.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%2Fgt19d74isa3bbgpy8xbb.png" alt="multi-module example"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2: The Dependency Management Dilemma&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The tricky part in multi-modules? Dependency management. &lt;br&gt;
As much as I loved the idea of app modularisation, I've realised it is not always sunshines and rainbows when it comes to managing dependencies.&lt;/p&gt;

&lt;p&gt;With 10 modules, you end up with 12+ build.gradle files, and they all look eerily similar. Take a look at this example of a typical /build.gradle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Alert! This might be a bit of eye sore, Lol)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
    id 'org.jlleitschuh.gradle.ktlint'
}

android {
    compileSdk 33
    defaultConfig {
        applicationId 'com.example.project.app'
        minSdk 26
        targetSdk 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_17
            targetCompatibility = JavaVersion.VERSION_17
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    namespace 'com.example.project.app'

    compileOptions {
        sourceCompatibility = 17
        targetCompatibility = 17
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
    }
    packagingOptions {
        resources.excludes.add("META-INF/*")
    }
}

repositories {
    mavenCentral()
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'com.jakewharton.timber:timber:5.0.1'

    // Compose dependencies
    implementation "androidx.compose.material:material:1.4.3"
    implementation "androidx.compose.ui:ui:1.4.3"
    implementation "androidx.compose.ui:ui-tooling-preview:1.4.3"
    testImplementation 'junit:junit:4.12'
    debugImplementation "androidx.compose.ui:ui-tooling:1.4.3"
    implementation 'androidx.activity:activity-compose:1.7.0'
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1"
    implementation "androidx.navigation:navigation-compose:2.5.3"
    implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'

    // DI dependencies - Dagger Hilt
    implementation "com.google.dagger:hilt-android:2.44.2"
    kapt "com.google.dagger:hilt-android-compiler:2.44.2"
    kapt "androidx.hilt:hilt-compiler:1.0.0"

    // Coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'

    // Local unit tests
    testImplementation "androidx.test:core:1.4.0"
    testImplementation "junit:junit:4.13.2"
    testImplementation "androidx.arch.core:core-testing:2.1.0"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1"
    testImplementation "com.google.truth:truth:1.1.3"
    testImplementation 'app.cash.turbine:turbine:0.12.1'
    testImplementation "io.mockk:mockk:1.13.8"
    debugImplementation "androidx.compose.ui:ui-test-manifest:1.1.0-alpha04"

    // Instrumentation tests
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.4.3"
    androidTestImplementation 'com.google.dagger:hilt-android-testing:2.37'
    kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.37'
    androidTestImplementation "junit:junit:4.13.2"
    androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.1"
    androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
    androidTestImplementation "com.google.truth:truth:1.1.3"
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test:core-ktx:1.4.0'
    androidTestImplementation "io.mockk:mockk-android:1.13.8"
    androidTestImplementation 'androidx.test:runner:1.5.2'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;I see two major problems here.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;First, all dependency versions are hardcoded.&lt;/u&gt;&lt;/strong&gt; &lt;br&gt;
Updating a library means updating multiple build.gradle files, a developer's nightmare. &lt;br&gt;
&lt;em&gt;(Typically, resolve this with versions object which I can talk about in the next post if anyone is interested.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Second, there's a ton of duplicated code&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
plugin IDs, Android configuration, compile options, and more.&lt;/p&gt;

&lt;p&gt;In this post, I want to talk about the &lt;strong&gt;second problem&lt;/strong&gt; above and how to eliminate the duplications and make the build gradles more &lt;strong&gt;organised and cleaner.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3: What can we expect from this post?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Spoiler Alert!!&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
I will show you what your build.gradle file would look like after following this approach. &lt;br&gt;
Remember, the eye-sore example above? &lt;br&gt;
Well, here is an updated version.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apply&amp;lt;ProjectGradlePlugin&amp;gt;()
plugins {
    `android-library`
    `kotlin-android`
}
android {
    namespace = "com.example.project.module"
}
dependencies {
    // After resolving first problem, let me know anyone 
    wants to read about how to update this dependencies 
    block.
    // Modules
    design()
    navigation()
    core_data()
    model()
    datastore()

    // Dependencies
    material()
    compose()
    googleSupportLibraries()
    networking()
    data()
}

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

&lt;/div&gt;

&lt;p&gt;🚀🚀🚀&lt;br&gt;
&lt;strong&gt;That's right, this is it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All those duplicated code is gone in this build.gradle file and now it is obviously much shorter and cleaner. &lt;/p&gt;

&lt;p&gt;How do we do this? Stay tuned in this post! &lt;/p&gt;

&lt;p&gt;Let's journey through the solution. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4: Solution: Build your own custom gradle plugin&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this chapter, we'll explore a practical solution for eliminating duplicated code in your multi-module Android project by creating your own custom Gradle plugin.&lt;/p&gt;

&lt;p&gt;Let's break it down into steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the buildSrc/ Module
&lt;/h3&gt;

&lt;p&gt;If you haven't already set up the buildSrc/ module in your project, now's the time to do it. You can create this directory at the root of your project by following these simple steps. &lt;br&gt;
This is also a great opportunity to migrate from Groovy to Kotlin DSL for your build.gradle files. If you decide to do so, don't forget to add the Kotlin DSL plugin in the build.gradle.kts file in buildSrc/.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins {
    `kotlin-dsl`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Step 2: Develop Your Custom Plugin
&lt;/h3&gt;

&lt;p&gt;Inside the buildSrc/src/ directory, create a Kotlin class that extends Plugin. You can name it whatever you prefer; for this post, let's call it "ProjectGradlePlugin." You'll need to override the apply function within this class.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ProjectGradlePlugin : Plugin&amp;lt;Project&amp;gt; {
    override fun apply(project: Project) {
     // Empty for now
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Step 3: Extracting Duplicate Code from build.gradle Files
&lt;/h3&gt;

&lt;p&gt;&lt;u&gt;a. Handling Plugins&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;You often find duplicated plugin declarations in your build.gradle files. &lt;br&gt;
To simplify, we'll extract these plugin declarations into your custom plugin class. However, you should leave Android library plugins in place, as they are required to create the Android block.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ProjectGradlePlugin : Plugin&amp;lt;Project&amp;gt; {
    override fun apply(project: Project) {
         // Applying plugins
         project.apply {
            plugin("kotlin-kapt")
            plugin("dagger.hilt.android.plugin")
            plugin("org.jlleitschuh.gradle.ktlint")
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can now remove those three lines from the build.gradle file. &lt;/p&gt;

&lt;p&gt;&lt;u&gt;b. Handling Android Block Configuration&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;The Android block in build.gradle files often contains a significant amount of duplicated code, such as SDK versions and build features. To streamline this, create an extension function for the Android block in your custom plugin class. This extension function returns the LibraryExtension Gradle class, allowing you to modify the Android configuration within your custom plugin.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    private fun Project.android(): LibraryExtension {
        return extensions.getByType(LibraryExtension::class.java)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then we call this function inside of our apply() function. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ProjectGradlePlugin : Plugin&amp;lt;Project&amp;gt; {
    override fun apply(project: Project) {
         // Applying plugins
         // Applying Configuration
         project.android().apply { 
            compileSdk = 33

            defaultConfig {
                minSdk = 21
                targetSdk = 33
                testInstrumentationRunner = ProjectConfig.testInstrumentationRunner
                consumerProguardFile(ProjectConfig.proguardFile)
            }
            buildFeatures {
                compose = true
            }
            compileOptions {
                sourceCompatibility = JavaVersion.VERSION_17
                targetCompatibility = JavaVersion.VERSION_17
            }
            composeOptions {
                kotlinCompilerExtensionVersion = "1.4.3"
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then we can remove the same codes inside of andorid {} in the original build.gradle file.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;c. Adding More Extensions&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;You can continue to extract and simplify further code blocks in a similar manner, such as specifying the Java version in the Kotlin block in your custom plugin.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Applying Your Custom Plugin
&lt;/h3&gt;

&lt;p&gt;Once you've extracted all the necessary code into your custom plugin, applying it is straightforward. Just add a single line to your build.gradle.kts file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apply&amp;lt;ProjectGradlePlugin&amp;gt;()&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;5: Summary&lt;/strong&gt;
&lt;/h2&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%2Fuploads%2Farticles%2Furpg0t9ddx6ac4x6eluc.jpeg" 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%2Furpg0t9ddx6ac4x6eluc.jpeg" alt="Finish"&gt;&lt;/a&gt;&lt;br&gt;
That's it! Your Gradle files are now cleaner and more organized. When you need to update configurations for your modules, you can simply make the updates within your custom project plugin. It's that easy!&lt;/p&gt;

&lt;p&gt;We've covered a lot of ground, but this approach can significantly simplify your multi-module Android project.&lt;/p&gt;

&lt;p&gt;But wait, the adventure continues! If you've got questions or awesome ideas swirling in your developer brain, don't hesitate. Share them in the comments below. Your solutions and suggestions are the secret sauce to our coding success! 🚀😄&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Useful resource&lt;/strong&gt;&lt;br&gt;
Here are useful articles that you might find helpful in case you are stuck with the points above. &lt;br&gt;
&lt;a href="https://medium.com/@ahmedeelkhami/multi-module-architecture-in-android-5f76373a84a7" rel="noopener noreferrer"&gt;Multi Module Architecture&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@dawinderapps/dependency-management-with-buildsrc-and-kotlin-dsl-f6826e2a2383" rel="noopener noreferrer"&gt;BuildSrc and Kotlin DSL&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/codex/clean-dependency-management-in-multi-module-android-projects-49f2a0df8d2f" rel="noopener noreferrer"&gt;Multi module architecture and BuildSrc&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/philipplackner/MultiModuleGradleManagement/tree/config_management" rel="noopener noreferrer"&gt;Public github project with custom gradle plugin implementation by Philipp Lackner &lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>gradle</category>
      <category>mobile</category>
      <category>programming</category>
    </item>
    <item>
      <title>KOTLIN COROUTINE: don't click, this post is only for myself</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Sun, 28 Mar 2021 09:20:06 +0000</pubDate>
      <link>https://dev.to/ham8821/kotlin-coroutine-don-t-click-this-post-is-only-for-myself-448d</link>
      <guid>https://dev.to/ham8821/kotlin-coroutine-don-t-click-this-post-is-only-for-myself-448d</guid>
      <description>&lt;p&gt;Hey there,&lt;br&gt;
If you are reading this post, that would mean that you are already curious about what I am going to talk about Kotlin coroutine in this post. And that's the case, my plan worked! Horay!!&lt;/p&gt;

&lt;p&gt;Yes, today in this post, I am going to talk about Kotlin coroutine which has been there for a while but for someone like me who haven't really get to use it so far or even get a heads around the concept itself and just really want to start it off with understanding it in a easy and straightforward way. So if you are already a kotlin coroutine expert, this post might be probably too easy for you then feel free to skip:)&lt;/p&gt;

&lt;p&gt;Enough for chit chat I guess, and let's just dive in!&lt;/p&gt;

&lt;h2&gt; Kotlin Coroutine: What is it? &lt;/h2&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%2Fuploads%2Farticles%2Fi1odsd8fi4muuxhsuc8a.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%2Fi1odsd8fi4muuxhsuc8a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before going straight into the topic, let me ask you something. &lt;br&gt;
Have you ever been in a frustrating situation where you are out for dinner date and all of a sudden feeling this urge that you really need to go to bathroom? And finally when you get there, you realise there is only one toilet stall and there are two people waiting in the line?&lt;br&gt;
How miserable!&lt;/p&gt;

&lt;p&gt;Wait how on earth is this related to today's topic? &lt;br&gt;
You are about to find out!&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%2Fuploads%2Farticles%2Fzre3zarkx1ig0ttav4n9.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%2Fzre3zarkx1ig0ttav4n9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Synchronous&lt;/b&gt;&lt;br&gt;
If you could relate to the situation described above. That means, in programming words, you were in "Synchronous" situation. &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%2Fuploads%2Farticles%2F7v7x77979jqycyx3lifc.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%2F7v7x77979jqycyx3lifc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;a job(or task) which is, in our case, using toilet can be completed one by one even if there are multiple people(tasks) waiting and we all know it can be quite annoying sometimes. &lt;/p&gt;

&lt;p&gt;&lt;b&gt; Asynchronous&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;But let's imagine what if there were a few stalls we could use! Then we wouldn't have had to wait for other people to come out. That case is what we call Asynchronous. &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%2Fuploads%2Farticles%2Fi30ka346bsjotkimkdsw.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%2Fi30ka346bsjotkimkdsw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, in Asynchronous, multiple tasks can be executing at the same time and also other tasks don't need to wait another task that executed before to be finished. &lt;/p&gt;

&lt;h3&gt;Okay, I think it is enough for toilet example. 
Let's talk some real coding example&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun getNetWorkData() {
    val requestRes = networkRequest()
    displayResponse(requestRes)
}

fun networkRequest(): Response {
    // doing some heavy lifting call.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's say there are two functions as you can see above. The first one "getNetworkData" is getting request response from networkRequest() call and displaying it on the screen. And let's just say that networkRequest() function is doing some heavy job probably making network call or some disk operations. &lt;/p&gt;

&lt;p&gt;The issue that we are facing here is that until the networkRequest() is completed, the other task print is blocked to be executed as this function is running on a main Thread just like we had only one toilet stall earlier(sorry for using this example again:( ). &lt;/p&gt;

&lt;p&gt;If this networkRequest() is taking too long, then in real programming world, the UI might be getting laggy or even freeze for a second while waiting &lt;b&gt;which would be very unpleasant to see as users&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;In an ideal world, we would want to move this non-UI related task &lt;b&gt;to a different thread&lt;/b&gt; so that the UI related tasks can be unblocked. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;This is where "Kotlin Coroutine" comes in!&lt;/b&gt;&lt;/p&gt;

&lt;h2&gt; Kotlin Coroutine: Concepts &lt;/h2&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%2Fuploads%2Farticles%2F083l474irij3d24mpci7.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%2F083l474irij3d24mpci7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;With that being said, let's modify the snippet earlier to coroutine way&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;suspend fun getNetWorkData() {
    val requestRes = networkRequest()
    displayResponse(requestRes)
}

suspend fun networkRequest(): Response {
    withContext(Dispatcher.IO) {
    // doing some heavy lifting call.
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Compare to how it looked previously, there were two modifications made. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;suspend&lt;/li&gt;
&lt;li&gt;withContext&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are the coroutine concepts we will cover in the later post. So please bear with me and let me just briefly explain what that block of code doing. It is pretty much when the networkRequest is running, making the network call to be made in the Thread called Dispatcher.IO rather than the same Thread that this UI is running to avoid blocked tasks. &lt;/p&gt;

&lt;p&gt;Wait, Dispatcher.IO.. is there more?&lt;/p&gt;

&lt;h4&gt;Yes&lt;/h4&gt;

&lt;h2&gt; Dispatcher &lt;/h2&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%2Fuploads%2Farticles%2F7fodorzw1d9umeyf4ffz.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%2F7fodorzw1d9umeyf4ffz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will mean that depending on the type of task that you want to run behind the scene, you can wisely choose the dispatcher type according to this. &lt;/p&gt;

&lt;h2&gt; Coroutine Scopes &lt;/h2&gt;

&lt;p&gt;Earlier, we have talked about "where" we would want to run our task and how to make that happen. &lt;/p&gt;

&lt;p&gt;Here we will talk about "When".&lt;br&gt;
What do you mean? &lt;br&gt;
Well, let's imagine we have a task that printing the text "running..." in the log every 1 second. Depending on the purposes, we might want to run this task while the app is active. For example, this text will be displayed from the start of an app and finished when the app is killed. Or we might also want to run the task for a particular time of an app and make the task is cancelled when it is no longer needed. "When" do we want this task and "When" do we not want this task to be run can be defined with "Coroutine Scope".&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%2Fuploads%2Farticles%2F4bez7pbr7t84pzg68qd3.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%2F4bez7pbr7t84pzg68qd3.png" alt="Alt Text"&gt;&lt;/a&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%2Fuploads%2Farticles%2Fxw2bggmww0ivtqxp4bz2.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%2Fxw2bggmww0ivtqxp4bz2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let me put  it this way, the method that I described above that prints "running.." in the log, this will be happening as long as the app is running if we use globalScope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    GlobalScope.launch {
       delay(1000)
       Log.d("coroutine", "running..")
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For lifecycleScope,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    lifecycleScope.launch {
       delay(1000)
       Log.d("coroutine", "running..")
       // Any coroutine launched in this scope is canceled when the Lifecycle is destroyed. 
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For viewModelScope,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    viewModelScope.launch {
       delay(1000)
       Log.d("coroutine", "running..")
       // Coroutine that will be canceled when the ViewModel 
      is cleared.
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt; We will dive in deeper in the next post! &lt;/h2&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%2Fuploads%2Farticles%2Fkfy4t4cqag8ijq1601mb.jpeg" 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%2Fkfy4t4cqag8ijq1601mb.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, in this post, we have covered the basic concept of Kotlin coroutine on what it is, why we need it, How we make sure when and where tasks are executed. &lt;/p&gt;

&lt;p&gt;In the second post, we will cover how we define the task in coroutine and how we make it run and how we make it finished with some real code examples. Hope now you guys have at least clear idea of what Kotlin coroutine is. And for more details in codes, don't worry we will get there once we have the second post! &lt;/p&gt;

&lt;p&gt;Links for references&lt;br&gt;
&lt;a href="https://developer.android.com/topic/libraries/architecture/coroutines" rel="noopener noreferrer"&gt;uptrends.com/tools/website-speed-test&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;https://kotlinlang.org/docs/coroutines-overview.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=C38lG2wraoo" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.youtube.com/watch?v=C38lG2wraoo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=C38lG2wraoo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Android: Accessing view, now what? (butterknife, viewbinding, databinding comparison)</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Mon, 29 Jun 2020 06:00:16 +0000</pubDate>
      <link>https://dev.to/ham8821/android-accessing-view-now-what-1jkg</link>
      <guid>https://dev.to/ham8821/android-accessing-view-now-what-1jkg</guid>
      <description>&lt;p&gt;Hey guys! It has been a while since the last post, hope you guys have been doing good and staying strong:) &lt;/p&gt;

&lt;p&gt;Recently, I have come across multiple ways to access layouts and bind those views with code so that we can use that views as we want. Sounds like we are going into the topic too straight away? &lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7aoev9Sb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/asu3gx908sth9b6tlvjv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7aoev9Sb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/asu3gx908sth9b6tlvjv.jpeg" alt="Alt Text" width="225" height="225"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
Well let me put this way, I have a xml file which has text field. In one of the fragments that I have, I want to set the text value or even decide on the visibility of the text field. Sounds like I should get the instance of the view in my fragment class. Then how do we do it? how do we create a bridge/connect these two seperate files and use one property in the other class? &lt;/p&gt;

&lt;p&gt;well again, like I said word "multiple" earlier, there are many. And needless to say if you are working on a exisiting project that has been there for a while, you might probably have come across the history of view binding in Android development(with a bit of exaggeration):)&lt;/p&gt;

&lt;p&gt;In this article, we will cover an overview of some of the most common and well used ways to make above possible in Android Development and talk about the general concept and some of the points that we can take into our accounts going forward.&lt;br&gt;
Especially, if you are trying to migrate or transit the way of it from old way to another way, then hopefully this article can give you a good insight. &lt;/p&gt;

&lt;h2&gt;Step1: What are there for us &lt;/h2&gt;

&lt;p&gt;There are five most common and well-known ways to do view binding. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oLhYR6eH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/gehyeutfcr2zyp2cises.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oLhYR6eH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/gehyeutfcr2zyp2cises.png" alt="Alt Text" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am sure that most of you are already aware of some of or all of these view binding libraries and possibly already been using it for a while. I am not going to go through each and every item and explain since it is just all about high level of the concept of view binding ways and just to give it a good understanding as myself was also confused since there were so many! (as you can see a bit of a frustration from the title "now what!")&lt;/p&gt;

&lt;h3&gt; A. FindViewByID&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ir7qCAEf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/cbbelntscjrsuzvry7d2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ir7qCAEf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/cbbelntscjrsuzvry7d2.png" alt="Alt Text" width="800" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we go, we have the most traditional and oldest way to bind views here. Initially, the traditional steps to take to be able to bind views with code is something like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inflate the XML&lt;/li&gt;
&lt;li&gt;Find the required element from the XML&lt;/li&gt;
&lt;li&gt;Assign it to a local/member variable&lt;/li&gt;
&lt;li&gt;Get the value from data&lt;/li&gt;
&lt;li&gt;Assign the value or Assign the event listener&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the second step when finding the required element from the XML, using this old way would required to code "findViewById", creating unnecessary boilerplates.This approach is being considered as outdated way and better to avoid to use. &lt;/p&gt;

&lt;h3&gt; B. Butterknife&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xm7G5qNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/efpnzkyzrdnep9iq6g5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xm7G5qNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/efpnzkyzrdnep9iq6g5d.png" alt="Alt Text" width="800" height="87"&gt;&lt;/a&gt;&lt;br&gt;
Butterknife was introduced in 2016 by Jake Wharton ever since its release, it had been considered one of the most best ways to replace "FindViewByID" since it was reducing a lot of boilerplates codes that original way was producing. &lt;br&gt;
In butterknife, there are Annotate fields with @BindView and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout like above. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;However, the story doesn't end here&lt;/b&gt;&lt;br&gt;
Guess what,&lt;br&gt;
Butterknife tool is now deprecated and feature development and general bug fixes have stopped as the author himself is recommending to switch to "viewbinding" which will be covered in this article later.(FYI, this author has now joined the team to work on viewbinding tool now). &lt;br&gt;
If you are interested to have a look at some documentations. check out this link.&lt;br&gt;
&lt;a href="https://github.com/JakeWharton/butterknife"&gt;https://github.com/JakeWharton/butterknife&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt; C. Kotlin Synthetic&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ffxJhOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/ovmysnl2q4pzlc5gzllr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ffxJhOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/ovmysnl2q4pzlc5gzllr.png" alt="Alt Text" width="800" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While butterknife was considered one of the best ways to do viewbinding. We also need to have a look at this one called Kotlin Syntehtic(also called Kotlin extensions). This one is, still in a lot of places, being considered the best way to do viewbinding for kotlin classes. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Why?&lt;/b&gt;&lt;br&gt;
Kotlin uses synthetic properties, and they are called on demand with a caching function (hence a small activity / fragment load), and ButterKnife binds all the views at the same time ButterKnife.bind() (which consumes a bit more time). With Kotlin you don’t even need to use annotation to bind to views. &lt;br&gt;
&lt;b&gt;Just use the id of the imported views!!!&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Yes, it also goes well with the RecyclerView + ViewHolder template, you just need to import kotlinx.android.synthetic.main.layout_main.view.* (If layout_main.xml is the name of the Activity / Fragment layout file).&lt;/p&gt;

&lt;p&gt;You do not need to make any extra effort to import the layout with include . &lt;br&gt;
&lt;b&gt;Just use the id of the imported views.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---16mYTCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/iatgodwxpc7xdklkpnw7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---16mYTCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/iatgodwxpc7xdklkpnw7.jpeg" alt="Alt Text" width="322" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;Sounds good so far? 
You are about to see more fascinating stuff&lt;/center&gt;

&lt;h3&gt; D. ViewBinding VS Databinding&lt;/h3&gt;

&lt;p&gt;Here is why I wanted to explain viewbinding and databinding together.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m3tF0OCI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/7z4wq3spozijbljfsou6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m3tF0OCI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/7z4wq3spozijbljfsou6.png" alt="Alt Text" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, viewbinding is a sort of subset of databinding libraries which means viewbinding and databiding can do the same jobs in terms of binding layouts. And it would also mean with databinding, you might not need viewbinding cause it will do what viewbinding is supposed to do and also provide a bit of an &lt;b&gt;extra functionalities such as 2way binding, and using variables in xml files.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;then, this can lead to a question &lt;br&gt;
"Then let's just use databinding as it sounds much more fancy!"&lt;/p&gt;

&lt;p&gt;Hold on. As much as it sounds fancy, it is pretty heavy loaded library which might cause a longer compile time. So if you are not going to use databinding only functionalities then might be better consider viewbinding as it does have some advantages in terms of build time and apk size. &lt;/p&gt;

&lt;p&gt;Also, apparently there are different steps need to take whenever using viewbinding functionalities with actual viewbinding library and databinding libarary.&lt;br&gt;
Here are some examples.&lt;/p&gt;

&lt;p&gt;** Adding  tag in xml file &lt;br&gt;
When we try to bind layouts using databinding, we need to go to that specific layout file and have to add  tag manually to be able to get the generated binding class which I know a lot of developers hate to do.&lt;/p&gt;

&lt;p&gt;** DataBindingUitil vs ActivityMainBinding(this one depends on the layout file name for example if the layout name is layout_login_fragment, it will be LayoutLoginFragmentBinding)&lt;/p&gt;

&lt;p&gt;if we are using these in Activity this will be inside of onCreate, if it is Fragment it will be inside of onCreateView .&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---JW8OcMf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/z1q1lep86xux7mdjp47k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---JW8OcMf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/z1q1lep86xux7mdjp47k.png" alt="Alt Text" width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some more links you can check&lt;br&gt;
&lt;a href="https://hackernoon.com/android-butterknife-vs-data-binding-fffceb77ed88"&gt;https://hackernoon.com/android-butterknife-vs-data-binding-fffceb77ed88&lt;/a&gt; butterknife vs databinding&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@hardianbobby/databinding-vs-viewbinding-simple-comparison-792fa8d72e8"&gt;https://medium.com/@hardianbobby/databinding-vs-viewbinding-simple-comparison-792fa8d72e8&lt;/a&gt; databinding vs viewbinding.&lt;/p&gt;

&lt;p&gt;And some simple comparison between all the libraries mentioned above. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ckE5_HlM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/zpqkvqb4uooaf5xn9ctm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ckE5_HlM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/zpqkvqb4uooaf5xn9ctm.png" alt="Alt Text" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have covered briefly about viewbinding ways on a high level in this article. Hopefully it gives you a better understanding of accessing views in Android and a bit of idea on which way that you will implement based on comparison here. &lt;/p&gt;

&lt;p&gt;If it is possible, would love to dig in on viewbinding and databinding a bit more and write something up on how to implement it or even replace one with the other. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SxgZuuwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/fy4a3p1766ozcuum79vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SxgZuuwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/fy4a3p1766ozcuum79vg.png" alt="Alt Text" width="512" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;h3&gt;Thanks for reading!&lt;/h3&gt;&lt;/center&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>dev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>WARNING: MEMORY LEAKS (feat. Java, Android Studio)</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Sun, 01 Mar 2020 03:22:40 +0000</pubDate>
      <link>https://dev.to/ham8821/warning-memory-leaks-feat-java-android-studio-1lhd</link>
      <guid>https://dev.to/ham8821/warning-memory-leaks-feat-java-android-studio-1lhd</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gSsEDSqh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/6rrtt6hkucsnglhfpa3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gSsEDSqh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/6rrtt6hkucsnglhfpa3j.png" alt="Alt Text" width="699" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, please raise your hands if you have seen this error showing up before? Or have you detected that your application is acting weird? Weird as in strange application crashes, Severe performance degradation when the application is continuously running for a long time? &lt;br&gt;
If this sounds familiar, there is a high chance that memory leaking is already happening in your app. &lt;/p&gt;

&lt;center&gt;&lt;h1&gt;1. What is MEMORY LEAK?&lt;/h1&gt;&lt;/center&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnOM2hN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/6ck4fmdw9m7kgj2cagrg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnOM2hN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/6ck4fmdw9m7kgj2cagrg.jpeg" alt="Alt Text" width="234" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know, in Java, Objects are saved in a memory area called the heap. As it sounds, in heap, we can store heaps of objects there though it sometimes increases and reduces in size. Unfortunately, this heap has a limited space and once it reaches the limit, you will get to see &lt;b&gt;OutOfMemoryError&lt;/b&gt; error message. &lt;br&gt;
&lt;a href="https://8thlight.com/blog/colin-jones/2017/03/17/everybody-ooms.html"&gt;Useful article about OOM Error&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Q&lt;/b&gt;: Then how can we clean the unnecessary memory? &lt;br&gt;
&lt;b&gt;A&lt;/b&gt;: Normally, there is a thing called GC(Garbage Collector)in Java that is periodically taking care of all the unused objects in memory. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;em&gt;GC: the built-in Garbage Collector (or GC for short). The GC implicitly takes care of allocating and freeing up memory and thus is capable of handling the majority of the memory leak issues.&lt;/em&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Q&lt;/b&gt;:  If Garbage collector can free up memory, why does this memory leak happen? &lt;br&gt;
&lt;b&gt;A&lt;/b&gt;: Let's have a look at the picture for better understanding! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KYSb7ltL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qn2yo0o2uc9iddk8nvw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KYSb7ltL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qn2yo0o2uc9iddk8nvw0.png" alt="Alt Text" width="299" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, When Garbage collector is freeing up the memory that is not being used, it checks that based on the fact that whether the object is unreferenced or referenced. If this object is identified as unreferenced object then GC will consider this as unused object to clean up and will get on with it. &lt;/p&gt;

&lt;p&gt;However, in real world, it is most likely that we have objects that are not being used really but still being referenced with other objects in the app. As expected, Garbage collector is obviously not capable of identifying those troublesome objects and as a result, those objects will stay not being properly handled, using up the amount of memory available for the app, which causes unexpected results.&lt;/p&gt;

&lt;p&gt;I mean, it is pretty much like, when we clean our room or when we move out, in a situation where we have to get rid of all the stuff that we are not actually using to start fresh, there are always some stuff that bug us all the time, right?&lt;br&gt;
If you are much of a collector, you would understand what I am saying. There is no doubt that you are not using them and haven't been using them for a long time but then there is always some references to it that makes you hesitate to remove them but if you keep keeping them in your room, these will take up the most of the space and you will need to somehow remove them. &lt;/p&gt;

&lt;center&gt;&lt;h1&gt;2. What could cause MEMORY LEAK?&lt;/h1&gt;&lt;/center&gt;

&lt;p&gt;In any application, memory leaks can happen for numerous reasons. There are 3 most common cases.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;1. Heavy use of static&lt;/b&gt;&lt;br&gt;
The first scenario that can cause a potential memory leak is heavy use of static variables.&lt;/p&gt;

&lt;p&gt;In Java, static fields have a life that usually matches the entire lifetime of the running application. Unless we set it NULL when we are done using, there is a possibility that these variable stay in memory and be a potential cause of leaks.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;2. Bitmaps&lt;/b&gt;&lt;br&gt;
Bitmap objects are quite heavy in general, and if they are dealt with improperly, they can lead to significant memory leaks that eventually crash your app due to OutOfMemoryError. Most of the time, theses objects have something to do with images and if they are not handled in framework, it is recommended to use recycle() after using them.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;3. Contexts&lt;/b&gt;&lt;br&gt;
Another common reason for memory leaks is the misuse of the Context instances. &lt;br&gt;
Context might sound familiar since is is commonly used as an abstract class that is extended to provide class' functionalities. &lt;/p&gt;

&lt;p&gt;However, there are two important types of contexts which are activity-level context and app-level context. If activity Context is used in a wrong place, this reference can be kept to entire activity and be a potential leak.&lt;br&gt;
&lt;a href="https://medium.com/@ali.muzaffar/which-context-should-i-use-in-android-e3133d00772c#.mruk222z2"&gt;Here is some article about types of Contexts in Android&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;h1&gt;3. How do we detect MEMORY LEAK?&lt;/h1&gt;&lt;/center&gt;

&lt;p&gt;If you are working on a big scale of application code written by someone else long ago and somehow you should figure out why this memory leak is happening, there are 2 amazing, recommended ways to do that.&lt;/p&gt;

&lt;center&gt;&lt;h3&gt;Profiler&lt;/h3&gt;&lt;/center&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CDY5Num9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/wc64l4040n4uwcu1647d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CDY5Num9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/wc64l4040n4uwcu1647d.png" alt="Alt Text" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Android docs, profiler is defined as below:&lt;br&gt;
The Memory Profiler is a component in the Android Profiler that helps you identify memory leaks and memory churn that can lead to stutter, freezes, and even app crashes. It shows a realtime graph of your app's memory use and lets you capture a heap dump, force garbage collections, and track memory allocations.&lt;/p&gt;

&lt;p&gt;So let's say that your device or emulator is connected to the android studio, and you open the profiler(normally View &amp;gt; Tool Windows &amp;gt; Profiler), and then let the application run for a bit. &lt;br&gt;
Then you will see something similar as this picture. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDMRRqtU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/jbeponodtt361npvurbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDMRRqtU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/jbeponodtt361npvurbe.png" alt="Alt Text" width="800" height="335"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.android.com/studio/debug/apk-debugger"&gt;&lt;/a&gt;&lt;a href="https://developer.android.com/studio/debug/apk-debugger"&gt;https://developer.android.com/studio/debug/apk-debugger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can carefully have a look into the graph and probably set the timing of the memory capture if needed to find out when the memory leak is happening, reading through the objects listed and identify whether these objects are supposed to be here or removed. If they exist when they are not supposed to be, this is where memory leak is detected and start thinking about optimizing the class.&lt;/p&gt;

&lt;p&gt;This profiler helps analysing memory data and provides so much filter and information in depth. &lt;br&gt;
For example, it provides,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What types of objects were allocated and how much space they use.&lt;/li&gt;
&lt;li&gt;The stack trace of each allocation, including in which thread.&lt;/li&gt;
&lt;li&gt;When the objects were deallocated (only when using a device with Android 8.0 or higher).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more information, &lt;a href="https://developer.android.com/studio/profile/memory-profiler"&gt;click Here to read documentations on profiler. &lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;h3&gt;LeakCanary&lt;/h3&gt;&lt;/center&gt;

&lt;p&gt;Profiler provides very useful insight and analysis on memory leak, being connected to devices and allow us to be able to simulate the scenario and play with those. However, Here is one more thing you might want to have a look. LeakCanary.&lt;/p&gt;

&lt;p&gt;LeakCanary is an Open Source Java library to detect memory leaks in your debug builds. The biggest advantage of using LeakCanary is that LeakCanary will automatically show a notification when an activity memory leak is detected in your debug build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UXJZobfc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/aurkelzfnoty48dzs69e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UXJZobfc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/aurkelzfnoty48dzs69e.png" alt="Alt Text" width="630" height="328"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://chromium.googlesource.com/external/github.com/square/leakcanary/+/refs/heads/jrod/false-negative/README.md"&gt;&lt;/a&gt;&lt;a href="https://chromium.googlesource.com/external/github.com/square/leakcanary/+/refs/heads/jrod/false-negative/README.md"&gt;https://chromium.googlesource.com/external/github.com/square/leakcanary/+/refs/heads/jrod/false-negative/README.md&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;h1&gt; 4. Conclusion&lt;/h1&gt;&lt;/center&gt;

&lt;p&gt;To sum up, as the size of the application is getting bigger, the harder it gets to troubleshoot app crashes and figure out the causes. In a same sense, since memory heap is not something clearly visible for us, it is really complicated to know exactly where and when the memory leak is happening. Using profiler and library such as LeakCanary, we can at least diagnose the problem with some meaningful data and analysis derived to start the troubleshooting on a right point. &lt;/p&gt;

&lt;h3&gt;More to read&lt;/h3&gt;

&lt;ol&gt;&lt;a href="https://chromium.googlesource.com/external/github.com/square/leakcanary/+/refs/heads/jrod/false-negative/README.md"&gt;1. Leak Canary Docs&lt;/a&gt;&lt;/ol&gt;

&lt;ol&gt;&lt;a href="https://github.com/square/leakcanary%0A"&gt;2. LeakCanary git docs&lt;/a&gt;&lt;/ol&gt;

&lt;ol&gt;&lt;a href="https://www.raywenderlich.com/4557771-android-memory-profiler-getting-started"&gt;3. Profiler Tutorial&lt;/a&gt;&lt;/ol&gt;

&lt;ol&gt;&lt;a href="https://developer.android.com/studio/debug/apk-debugger%0A"&gt;4. Profiler Docs&lt;/a&gt;&lt;/ol&gt;

&lt;ol&gt;&lt;a href="https://www.baeldung.com/java-memory-leaks%0A"&gt;5. Understanding of Memory Leak in Java&lt;/a&gt;&lt;/ol&gt;

&lt;ol&gt;&lt;a href="https://raygun.com/blog/memory-leak-detection/%0A"&gt;6. Memory Leak Detection&lt;/a&gt;&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fssJVcPI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/oi583paddord06u960lc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fssJVcPI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/oi583paddord06u960lc.jpg" alt="Alt Text" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>android</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is your new year's resolution as a developer?</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Thu, 02 Jan 2020 22:51:13 +0000</pubDate>
      <link>https://dev.to/ham8821/what-is-your-new-year-s-resolution-as-a-developer-4ja1</link>
      <guid>https://dev.to/ham8821/what-is-your-new-year-s-resolution-as-a-developer-4ja1</guid>
      <description>&lt;p&gt;What is your new year's resolution as a developer?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Super basic: How Hashmap works in Java</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Thu, 02 Jan 2020 11:01:04 +0000</pubDate>
      <link>https://dev.to/ham8821/super-basic-of-hashmap-in-java-53be</link>
      <guid>https://dev.to/ham8821/super-basic-of-hashmap-in-java-53be</guid>
      <description>&lt;p&gt;Hi there! &lt;br&gt;
It is 2020 already and what's a better way to start off the new year than to recap what we've already know such as how to walk and breathe and get drunk? LOL&lt;/p&gt;

&lt;p&gt;Today I might bring up some real basic concepts of hashmap in Java. I am pretty sure a lot of you already know better than anyone on this one. If that's the case, feel free to click the go back button but if you are a little unsure or have no idea what I am talking about, it is up to you spend 2 minute reading this article!&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fecdxv5cfrdikmi1dvmcw.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fecdxv5cfrdikmi1dvmcw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, the most well known definition of has a hash map would be a data structure that implements an associative array abstract data type, a structure that can map keys to values. &lt;/p&gt;

&lt;p&gt;To make it even easier,&lt;br&gt;
you know when we think of an array, we would probably think of a number index to access to a certain value. ex) arrayName[index]= value&lt;br&gt;
Same goes to hash map except that we can use key instead of number index values. &lt;br&gt;
As shown in the image below, the hashmap is an array of nodes that has Key and Value which makes look ups to be much easier and more efficient by using key values. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5yegc74vqi31p995cex3.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5yegc74vqi31p995cex3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we look into the hashmap slightly more in detail, we can see it looks like a table that has nodes so called buckets which can represent a class having following objects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;K key : key string value that we use for look ups&lt;/li&gt; 
&lt;li&gt;int hash: integer hashcode from the string key value&lt;/li&gt;
&lt;li&gt;V value: the actual value that we want to access&lt;/li&gt;
&lt;li&gt;Node next: to point out the next entry or node&lt;/li&gt;
&lt;/ol&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgypef44ga06v9myhd5gf.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgypef44ga06v9myhd5gf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, now we kinda understand what the hashmap is, then it is time for us to have a try to work with it to understand how it actually works.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F21lvpc0ivk064ce74j0i.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F21lvpc0ivk064ce74j0i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To explain the steps in order to access to a certain value using key, first of all, I would like to insert some values into the map first for better understanding.&lt;/p&gt;

&lt;p&gt;To insert the values, we can use put(k,v) method and to to that, let's quickly create a simple hashmap called scroes where we will be storing the names and scores accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HashMap&amp;lt;String, integer&amp;gt;scores = new HashMap&amp;lt;String, Integer&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the hashmap is created, the size of the map will be automatically initialised by 16 which makes the index of the map starts from 0 and finishes to 15. &lt;/p&gt;

&lt;p&gt;Now let's say we want to put these three records into the scores map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
scores.put("Smith","100");
scores.put("Blake","87");
scores.put("King","100");

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

&lt;/div&gt;



&lt;p&gt;To start with the first record, we will be going through this put() method as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;put(K k, V v)

hash(k)

index = hash &amp;amp; (n-1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go ahead and start inserting the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;put(K k, V v) // k = "Smith" and v = "100"

hash(k) // This will get the hash of the string key. in this case hash("SMITH")= 79019862

index = hash &amp;amp; (n-1)// n= 16 and index will be 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this process, the map will look 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fun210mb6l5m07q7rflfw.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fun210mb6l5m07q7rflfw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After following the same steps for all the records, the map will end up looking like below&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0umc9q5lp9a4ys58vq2g.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0umc9q5lp9a4ys58vq2g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;notice: I forgot to change the hash value for the second record for Kings in the picture. just note that the hash value for king is different from the one for Blake&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wait, hold on a second, some of you might have noticed that we have 2 records in index 4 node. How did this happen?&lt;/p&gt;

&lt;p&gt;If we scroll back a bit up to where we get the index by hash &amp;amp; (n-1), we can check those two records end up having same index which is 4 in this case. Let's say we tried to put Blake's record first and there shouldn't have been any problem, like we understood the data "Blake | hash| score| null" must have been inserted.&lt;/p&gt;

&lt;p&gt;But as we insert Kings record after, we will figure out that they have same index number, the map will automatically put the record next to the Blake's record by changing the null value to point out to the next node which is King's in this case. That is how the outcome looks like the map above.&lt;/p&gt;

&lt;p&gt;This will also lead us to this question. &lt;br&gt;
"If they have same index number, how do we access to them?"&lt;/p&gt;

&lt;p&gt;In order to access to the nodes, we can use get(k) method.&lt;br&gt;
This method looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;V get(Object key)
hash(key)

Index = hash &amp;amp; (n-1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's say we want to find King's score in this hashmap using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scores.get("King")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then it will get the hash which is 2306996 and will get the index number which is 4 in this case. In the first node which has index 4, it will compare hashcode between the hascode that we are looking for and the hashcode that this node has. For example, the hascode we are looking for is 2306996 and the node has 63281940 as a hash value. They don't match, so it will be pointed out to the next node which and will do the comparison again. This time the hash value do match since it has 2306996 which we are looking for. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwu30lyqaq0ovyq200alx.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwu30lyqaq0ovyq200alx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;notice: I forgot to change the hash value for the second record for Kings. just note that the hash value for king is different from the one for Blake&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Alright!&lt;br&gt;
Today, we have talked about some of the basic concepts of hashmap. Actually, the reason I brought this topic up today was that I realised that hashmap come across very often we we code and it is very easy to just overlook, thinking that we understand how it works 100%. However, when I faced some complicated issues, I realised that I wasn't really understanding how it works and how to use it properly. I hope it helped for some of you guys to understand little bit better about hashmap and not get confused later when we really need to go through some concepts along the way of programming.&lt;/p&gt;

&lt;p&gt;Thanks a lot for your time to read this article and Happy new year!!!&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7vic0dq4z6bg3zet3ixc.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7vic0dq4z6bg3zet3ixc.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>devops</category>
      <category>beginners</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>What do you think about whiteboard interview?</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Wed, 30 Oct 2019 20:59:45 +0000</pubDate>
      <link>https://dev.to/ham8821/what-do-you-think-about-whiteboard-interview-185m</link>
      <guid>https://dev.to/ham8821/what-do-you-think-about-whiteboard-interview-185m</guid>
      <description></description>
      <category>discuss</category>
      <category>devops</category>
    </item>
    <item>
      <title>SOLID PRINCIPLES: To start with Object-oriented programming</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Tue, 17 Sep 2019 11:17:18 +0000</pubDate>
      <link>https://dev.to/ham8821/solid-principles-to-start-with-object-oriented-programming-1e49</link>
      <guid>https://dev.to/ham8821/solid-principles-to-start-with-object-oriented-programming-1e49</guid>
      <description>&lt;p&gt;Hi everyone, today I would like to discuss about something solid. &lt;br&gt;
solid? Of course, no! Not that solid.&lt;br&gt;
wait... ah maybe exactly that solid! &lt;/p&gt;

&lt;p&gt;I went to an interview today and was asked this question about "&lt;b&gt;Solid principles&lt;/b&gt;". And I was like "um... not really sure" which means "I don't know what you are talking about". &lt;br&gt;
 On my way out of the room, I felt like I was definitely in a need of researching about solid principles to properly start off going further to object-oriented programming world in the right direction.&lt;/p&gt;

&lt;p&gt;So today, I would like to cover this topic with a few basic definitions and easy examples to help ourselves out to understand the concept in general.&lt;/p&gt;

&lt;h3&gt; 1) What and why :&lt;b&gt; SOLID PRINCIPLES&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M5txnJWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/oa222flxjd2uc1r0vdnz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M5txnJWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/oa222flxjd2uc1r0vdnz.jpeg" alt="Alt Text" width="740" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;SOLID stands for..&lt;/h4&gt;

&lt;p&gt;S.O.L.I.D is an acronym for the first five object-oriented design(OOD)** principles** by Robert C. Martin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KuxjHavd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/51ggtko1k9rhhmvr00mi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KuxjHavd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/51ggtko1k9rhhmvr00mi.png" alt="Alt Text" width="362" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is just really about a set of principles that we can keep in mind in terms of coding, refining and structuring code.&lt;/p&gt;

&lt;h4&gt;SOLID does..&lt;/h4&gt;

&lt;p&gt;By reading it, I had no idea what it is supposed to mean,by all mean. As far as understand, These principles are all about making it easier and cleaner for developers to develop software which are easy to maintain and modify when the scale of it is going bigger and get more complicated. So we can really understand this concept as a way of approaching object-oriented programming by cutting down the unnecessary part and organize the code in a way of refining and re-structuring.&lt;/p&gt;

&lt;h3&gt; 2) Dive into :&lt;b&gt; SOLID PRINCIPLES &lt;/b&gt;
&lt;/h3&gt;

&lt;h4&gt;First Principle: Single-responsibility Principle&lt;/h4&gt;

&lt;h4&gt;&lt;b&gt;"A class should have one and only one reason to change, meaning that a class should have only one job."&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;It is as simple as it sounds which means that a class should only perform a single job not the multiple jobs in a same class. &lt;br&gt;
Let's have a look at the example down.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Book {
  protected $Author;

  public getAuthor($Author) {
    return $this-&amp;gt;Author;
  }

  public function formatJson() {
    return json_encode($this-&amp;gt;getAuthor());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think, do you think you are getting a hang of it? &lt;br&gt;
We can clearly see that Class named 'Book' is performing more than one job which are getting the author of a book and also it is encoding the output to Json format. But what if we want to have an output in a different format not only Json? In that case, we probably have to write few more lines to add more method for that or modifying the existing code. It could look like a minor work at the moment because this example we have right here is extremely simple but imagine there are hundreds or even thousands of classes, it would be better off preventing confusions in advance by implementing these principles.&lt;/p&gt;

&lt;p&gt;So, the approach that we can take would be something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Book {
  protected $Author;

  public getAuthor($Author){
    return $this-&amp;gt;Author;
  }
}

class JsonBookForm {
    public function format(Book $Author) {
        return json_encode($Author-&amp;gt;getAuthor());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing that, If we want to get a different type of output then we don't need to make a change in the Book class directly.&lt;/p&gt;

&lt;h4&gt;Second Principle: Open-closed Principle&lt;/h4&gt;

&lt;h4&gt;&lt;b&gt;"Objects or entities should be open for extension, but closed for modification."&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;I know it is getting boring, but this is actually meaning that classes should be extended to change functionality, rather than being modified. It should be a way of extending its functionality when they want to add more options and it should not be the case just changing the existing code directly.&lt;/p&gt;

&lt;p&gt;There is a common example which is like down below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Triangle{
  public $width;
  public $height;
}

class Board {
  public $triangles= [];
  public function calculateArea() {
    $area = 0;
    foreach ($this-&amp;gt;triangles as $triangle) {
      $area += $triangle-&amp;gt;width * $triangle-&amp;gt;height* 1/2;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a Triangle class that contains the data for a Triangle which are width and height, and a Board class that is used as a array of Triangle objects. &lt;br&gt;
This code at the moment looks absolute fine but when you think about shape and calculating area function, maybe you might want to use this function later for other shapes as well not only just triangle to increase the efficiency. At the moment, these lines of codes are not allowing this by limiting the Board class only working with the Triangle class.&lt;/p&gt;

&lt;p&gt;The approach we can try here is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Shape {
   public function area();
}

class Triangle implements Shape {
  public function area() {
    return $this-&amp;gt;width * $this-&amp;gt;height *1/2;
  }
}
class Circle implements Shape {
  public function area() {
    return $this-&amp;gt;radius * $this-&amp;gt;radius * pi();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Board {
  public $shapes;

  public function calculateArea() {
    $area = 0;
    foreach ($this-&amp;gt;shapes as $shape) {
      $area+= $shape-&amp;gt;area();
    }
    return $area;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, we don't need to specify the name of the class in the class name Board, so whenever we want to add more properties something like Rectangle we can easily add a class named itself and implements Shape interface so that we can use area() in a Board class. &lt;/p&gt;

&lt;h4&gt;Third Principle: Liskov substitution principle&lt;/h4&gt;

&lt;h4&gt;&lt;b&gt;"Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T."&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;Okay, I know it does sound like my math teacher back in high school. can't really follow. &lt;br&gt;
But look at this picture here&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---PDMM_dL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/x4jct82537g2x3ta0ti1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---PDMM_dL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/x4jct82537g2x3ta0ti1.png" alt="Alt Text" width="200" height="200"&gt;&lt;/a&gt;&lt;br&gt;
Does this look familiar? We have probably seen this picture in school and I am sure your math teacher must have mentioned it. Where this graph can be implied in our world is something related to the previous example. Shapes. &lt;/p&gt;

&lt;p&gt;Speaking of shapes, there are a lot of shapes, right? There are circles, and triangles and rectangles and square.. wait, we all know that rectangle and square are similar but not same right? &lt;br&gt;
Rectangle includes square in terms of the fact that rectangle needs more conditions to be square. So it would be like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kIExkYSK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vg9vpqa159e2j3clgvmn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kIExkYSK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vg9vpqa159e2j3clgvmn.png" alt="Alt Text" width="200" height="200"&gt;&lt;/a&gt;&lt;br&gt;
***oops  I put the name the other way around here!!! &lt;br&gt;
The common code we can do here would be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Rectangle {
  public function setW($w) { 
      $this-&amp;gt;width = $w;
  }

  public function setH($h) {
      $this-&amp;gt;height = $h;
  }

  public function Area() {
      return $this-&amp;gt;height * $this-&amp;gt;width;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Square extends Rectangle {
  public function set($w) {
    $this-&amp;gt;width = $w;
    $this-&amp;gt;height = $w;
  }

  public function setH=($h) {
    $this-&amp;gt;height = $h;
    $this-&amp;gt;width = $h;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But did you realize that there are multiple lines looking exactly same? and considering the fact that in this tutorial, we are doing our best to make the code maintainable and efficient, this way should be avoided and rather trying this way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Setshape {
  public function setH($h);

  public function setW($w);

  public function Area();
}

class Rectangle implements Setshape ;

class Square implements Setshape ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing this way, we don't have to write the same code over and over again, and we can just simple implements the interface to the class.&lt;/p&gt;

&lt;h4&gt;Forth Principle: Interface segregation principle&lt;/h4&gt;

&lt;h4&gt;&lt;b&gt;"A client should never be forced to implement an interface that it doesn't use or clients shouldn't be forced to depend on methods they do not use."&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;We are almost there, the forth principle means that classes should not be forced to implement interfaces they do not use. For example, let's say there are some classes looking like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Employee {

  public function generatereport()

  public function clockin()

  public function clockout()

  public function customerservice()

  public function getPaid()

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

&lt;/div&gt;



&lt;p&gt;And let's say there is a duty manager who is doing the most of the functions above but not clockin and clockout because the could possibly get salary not hourly so for them those two functions will be never used.  To follow the principle here once again, we should approach it this way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Generalemployee{
 public function clockin()
 public function clockout()
}

interface Employee{
 public function customerservice()
 public function getPaid()
}

interface management{
  public function generatereport()
}

class Staff implements Generalemployee, Employee{
}

class Manager implements Employee, management{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Last Principle: Dependency Inversion principle&lt;/h4&gt;

&lt;h4&gt;&lt;b&gt;"Entities must depend on abstractions not on concretions. It states that the high level module must not depend on the low level module, but they should depend on abstractions."&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;I will go straight to the example for this one&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Getuserlists {
    private $dbConn;

    public function __construct(MySQLConn, $dbConn) {
        $this-&amp;gt;dbConn= $dbConn;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is common mistake because according to the hierarchy structure, Getuserlists class is higher module and MySQLConn is a lower module, however, you can easily notice that the class is depending on MySQLConn thoroughly and it would confuse later if we want to use other database not just MySQL.&lt;/p&gt;

&lt;p&gt;So the solution on this would be...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface DbConnectionInterface {
    public function connect();
} 

class MySqlConn implements DbConnectionInterface {
    public function connect() {}
}

class Getuserlists {
    private $dbConn;
    public function __construct(DbConnectionInterface $dbConn) {
        $this-&amp;gt;dbConn= $dbConn;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the little snippet above, you can now see that both the high level and low level modules depend on abstraction.&lt;/p&gt;

&lt;h2&gt;Congratulations!! We took a step towards Object-oriented programming world!! &lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o64q1J0Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5bjlddzr1dxvntsp2ro5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o64q1J0Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5bjlddzr1dxvntsp2ro5.jpg" alt="Alt Text" width="284" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;SOLID principles seemed to be a very confusing at first, and still will have some more struggles in order to make it to mine and get to the point where I can use comfortably without even realizing but It is always good to have some guidelines we can follow, isn't it?&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>php</category>
      <category>devops</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to optimize your website(feat.brotli Compression)</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Wed, 04 Sep 2019 05:13:49 +0000</pubDate>
      <link>https://dev.to/ham8821/how-to-optimize-your-website-feat-brotli-compression-4fea</link>
      <guid>https://dev.to/ham8821/how-to-optimize-your-website-feat-brotli-compression-4fea</guid>
      <description>&lt;p&gt;Hi everyone! &lt;br&gt;
Last time, I talked about Gzip compression which is one of the most common way to encode content, and someone have mentioned about brotli by Google. &lt;br&gt;
For that reason, today I would to talk little bit about brotli. &lt;br&gt;
If you haven't read my last post about Gzip compression, please &lt;a href="https://dev.to/ham8821/how-to-optimize-your-php-website-feat-gzip-compression-285j"&gt;Jump on here!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WOSNcAUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/8nyyy6i52jk4draxox4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WOSNcAUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/8nyyy6i52jk4draxox4g.png" alt="Alt Text" width="577" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, like mentioned above, Gzip is one of the popular and common ways of content encoding yet very useful in terms of the fact that it is easy to use because it can be executed simply by adjusting the setting provided by web server. &lt;br&gt;
However, at the same time it is getting critics because it is not perfect when it comes to security problems.&lt;/p&gt;

&lt;h3&gt;FIRST: Birth of &lt;b&gt;Brotli&lt;b&gt;&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;In September 2015, Google released the Brotli as a open source and then it started getting popular as chrome started supporting brotli compression.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l3TpUPZb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/esndcsj37d8xd6ngi6m3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l3TpUPZb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/esndcsj37d8xd6ngi6m3.jpg" alt="Alt Text" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;SECOND: &lt;b&gt;Gzip VS Brotli&lt;b&gt;&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;I know, You must be curious about which one is the best and I know always there would some discussions and different opinions on this.&lt;br&gt;
But, according the this &lt;a href="https://cran.r-project.org/web/packages/brotli/vignettes/benchmarks.html"&gt;article&lt;/a&gt; which is comparing some of the compression technology including gzip and brotli, &lt;br&gt;
&lt;b&gt;less means better&lt;b&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3SgXqzLH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/61dtua60n66fukz1f7gl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3SgXqzLH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/61dtua60n66fukz1f7gl.png" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UWC0qc_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/p9625dobfaotno3vcxmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UWC0qc_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/p9625dobfaotno3vcxmd.png" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is concluded that in terms of ratio of compression, brotli is showing the best result, yet in the compression speed area, gzip is showing the better result.&lt;/p&gt;

&lt;p&gt;If you want to have a look at more articles on this, the links below might help you to understand more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hacks.mozilla.org/2015/11/better-than-gzip-compression-with-brotli/"&gt;1)&lt;/a&gt;&lt;a href="https://hacks.mozilla.org/2015/11/better-than-gzip-compression-with-brotli/"&gt;https://hacks.mozilla.org/2015/11/better-than-gzip-compression-with-brotli/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/oyotech/how-brotli-compression-gave-us-37-latency-improvement-14d41e50fee4"&gt;2)&lt;/a&gt;&lt;a href="https://medium.com/oyotech/how-brotli-compression-gave-us-37-latency-improvement-14d41e50fee4"&gt;https://medium.com/oyotech/how-brotli-compression-gave-us-37-latency-improvement-14d41e50fee4&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt; THIRD: Using &lt;b&gt;Brotli&lt;b&gt; on &lt;b&gt;Nginx&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;Obviously, nginx is one of the web servers that has so many benefits. However, when we use brotli, it might require bit of an extra work. &lt;br&gt;
If nginx version has been changed, we need to accordingly compile and reset the setting which sounds quite annoying at this point.&lt;br&gt;
In order to reduce the extra work, there are some ways to automate these steps on internet yet it is not perfect.&lt;/p&gt;

&lt;p&gt;Here are some links about Brotli support&lt;br&gt;
&lt;a href="https://github.com/pothi/nginx-brotli"&gt;1) &lt;/a&gt;&lt;a href="https://github.com/pothi/nginx-brotli"&gt;https://github.com/pothi/nginx-brotli&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/engintron/engintron/issues/712"&gt;2) Brotli with Engintron Nginx&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt; LAST: &lt;b&gt;Conclusion&lt;b&gt;&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lzwQ0KbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/s764t2yradrhxiyuzuya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lzwQ0KbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/s764t2yradrhxiyuzuya.png" alt="Alt Text" width="662" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To sum up, Brotil is probably the best way to execute the content encoding comparing to previous deflate or gzip when we consider the fact that it definitely increases the ratio of compression and obviously reduces the loading time at maximum 20%. However, there are still some discussions about whether it is also better way for dynamic contents websites not only for static websites. Also, we need to keep an eye on the fact that it might be high-maintenance in some ways.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to optimize your php website(feat.Gzip Compression)</title>
      <dc:creator>Emma Ham</dc:creator>
      <pubDate>Tue, 03 Sep 2019 02:50:15 +0000</pubDate>
      <link>https://dev.to/ham8821/how-to-optimize-your-php-website-feat-gzip-compression-285j</link>
      <guid>https://dev.to/ham8821/how-to-optimize-your-php-website-feat-gzip-compression-285j</guid>
      <description>&lt;p&gt;Have you ever experienced when you grind your soul to make this website beautiful and once you deploy it online, It just takes forever to load and you feel bloody awkward in front of others cuz they also have to wait for eternal?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;common we've all been there&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Things get normally worse if it is deployed on free hosting website such as heroku, github.it etc. &lt;/p&gt;

&lt;p&gt;Then, What we can do about it.&lt;/p&gt;

&lt;h3&gt; &lt;b&gt;FIRST&lt;b&gt;: a diagnosis&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;As simple and obvious as it sounds, we need to first figure out how slow the website is and what are the causes, just like we receive a diagnosis from doctors!&lt;br&gt;
In order to do this, there are some useful links you might want to bookmark. &lt;br&gt;
Even though I know for a fact that there are hundreds of websites that do the similar works but it is purely the matter of a taste and these two are my favorite in terms of simple and straight forward UI designs and its contents.&lt;/p&gt;

&lt;p&gt;a. &lt;a href="https://www.uptrends.com/tools/website-speed-test" rel="noopener noreferrer"&gt;uptrends.com/tools/website-speed-test&lt;/a&gt;&lt;br&gt;
b. &lt;a href="https://tools.pingdom.com/" rel="noopener noreferrer"&gt;tools.pingdom.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, this is how it looks when you click the second link which is pingdom which helped me a lot to look at the problem clearly. You can simply copy your website url and select the location that you want to test from. And hit the "Start test" button!&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuhuyev0oblc4glt3mpcl.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuhuyev0oblc4glt3mpcl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's have a look at the result.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzb6be83b3ygbuna2iy7u.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzb6be83b3ygbuna2iy7u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seems like the overall performance grade is not so terrible, however I had a "D" grade under the name of 'Compress components'.&lt;br&gt;
It is saying&lt;/p&gt;

&lt;h6&gt;"Compression reduces response times by reducing the size of the HTTP response. Gzip is the most popular and effective compression method currently available and generally reduces the response size by about 70%. Approximately 90% of today's Internet traffic travels through browsers that claim to support gzip."&lt;/h6&gt;

&lt;p&gt;Alright, it sounds like it is time for us to dig into "gzip" part, doesn't it?&lt;/p&gt;

&lt;h3&gt; &lt;b&gt;SECOND&lt;b&gt;: Gzip, what are you?&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;Before, we get to the Gzip, it would be easier to understand the concept of content encoding with some explanations 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fltrvefjf0vnj30g5mdcf.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fltrvefjf0vnj30g5mdcf.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;Original&lt;/h6&gt;

&lt;p&gt;Browser: Hey dude, can I get index.php file?&lt;br&gt;
Server: Give a sec, wait....Yes! got it!  I’m sending the file to you.&lt;br&gt;
Browser: 200KB? Ouch… waiting, I am gonna need more time… ok, it’s done and loaded.&lt;/p&gt;

&lt;h6&gt;After Compression&lt;/h6&gt;

&lt;p&gt;Browser: Hey dude, can I get index.php file? I wouldn't mind a compressed version if you have any.&lt;br&gt;
Server: Give a sec, wait....Yes! got it! You said you are good with compressed one? amazing. I’m sending the file to you.&lt;br&gt;
Browser: Great! It’s only 20KB. I’ll unzip it myself!&lt;/p&gt;

&lt;p&gt;It is as simple as that! Smaller file can reduce so much time to download so that users don't have to wait for a long time to see the whole websites.&lt;/p&gt;

&lt;h3&gt; &lt;b&gt;THIRD&lt;b&gt;: Gzip, How can I have you?&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;Okay, let's get to the point right now to actually implement Gzip to our websites. It is going to be quite straight forward yet the syntax can varies so have that in mind!&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Firstly,&lt;/b&gt; Open your .htaccess file in your root folder. If you don't have it, then you can simply make one. In side of that file, what we can do is to specify the type of file that we want to compress. I would look like this.&lt;/p&gt;

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

&amp;lt;IfModule deflate_module&amp;gt;
    # Enable compression for the following file types.
    AddOutputFilterByType            \
     DEFLATE                         \
      application/javascript         \
      text/css                       \
      text/html                      \
      text/javascript                \
      text/plain                     \
      text/xml
&amp;lt;/IfModule&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;But note that Gzip is not able to compress which is already compressed in a way of compressed formats such as PNG, Zip or any other compressed formats.&lt;/p&gt;

&lt;p&gt;In Apache, this would work too&lt;/p&gt;

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

# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript


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

&lt;/div&gt;

&lt;p&gt;If above doesn't work, then try this one here&lt;/p&gt;

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

&amp;lt;ifModule mod_gzip.c&amp;gt;
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_include mime ^text/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_include handler ^cgi-script$
&amp;lt;/ifModule&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Secondly,&lt;/b&gt; Put this php code on the top of your main pages&lt;/p&gt;

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

&amp;lt;?php
if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
    ob_start();            
}
elseif (strpos(' ' . $_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') == false) {
    if (strpos(' ' . $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') == false) {
        ob_start();
    }
    elseif(!ob_start("ob_gzhandler")) {
        ob_start();
    }   
}
elseif(!ob_start("ob_gzhandler")) {
    ob_start();
}
?&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Thirdly,&lt;/b&gt; Let's go ahead and check if the compression is working!&lt;br&gt;
&lt;a href="http://www.gidnetwork.com/tools/gzip-test.php" rel="noopener noreferrer"&gt;gidnetwork.com/tools/gzip-test.php&lt;/a&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3s38ksls9jhb8cd47ylr.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3s38ksls9jhb8cd47ylr.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Horray! it said that is is compressed right and type of compression is gzip. Looks like we've done our job here:)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Lastly, Little extra&lt;/b&gt; If you are not still satisfied with the speed.&lt;/p&gt;

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

## EXPIRES CACHING ##
&amp;lt;IfModule mod_expires.c&amp;gt;
ExpiresActive On
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
&amp;lt;/IfModule&amp;gt;
## EXPIRES CACHING ##



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

&lt;/div&gt;

&lt;p&gt;Put those lines above in  .htaccess file. What it does is the mentioned file will be stored in caching and expire after a certain time so if you visit the website again few days later and you won't need to wait for the browser to load all the files all over again!&lt;/p&gt;

&lt;h3&gt; &lt;b&gt;Finally&lt;b&gt;: Let's check again how it worked on the website&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;I clicked the first link to check the speed and it is how it turned out!&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1jux83vpbbdois5p4ozg.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1jux83vpbbdois5p4ozg.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wow, looks pretty cool and sounds like I reduce some loading time obviously.&lt;/p&gt;

&lt;h3&gt; &lt;b&gt;Conclusion:&lt;b&gt;:&lt;/b&gt;&lt;/b&gt;
&lt;/h3&gt;

&lt;p&gt;By compressing your site’s files, you can make sure loading time stay low, and your users don’t suffer from unnecessary slowdowns.&lt;br&gt;
I hope this article would help you somehow and please let me know if you found this content useful Thank you!&lt;/p&gt;

&lt;p&gt;If you want to have a look my website &lt;br&gt;
&lt;a href="https://emmaham-portfolio.herokuapp.com/" rel="noopener noreferrer"&gt; Come and visit here&lt;/a&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3druws88n6n6c2zmzwjh.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3druws88n6n6c2zmzwjh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>gzip</category>
      <category>loadingtime</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
