<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>stories &#8211; Hand-Picked</title>
	<atom:link href="https://hand-picked.io/tag/stories/feed/" rel="self" type="application/rss+xml" />
	<link>https://hand-picked.io</link>
	<description>Top-notch remote software developers</description>
	<lastBuildDate>Mon, 19 Jul 2021 21:30:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.6.16</generator>

<image>
	<url>https://hand-picked.io/wp-content/uploads/2019/04/cropped-logo_512-2-32x32.png</url>
	<title>stories &#8211; Hand-Picked</title>
	<link>https://hand-picked.io</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>A Tale of Two HashMaps, or the importance of reading developer docs</title>
		<link>https://hand-picked.io/tale-of-hashmaps-or-the-importance-of-reading-docs/</link>
					<comments>https://hand-picked.io/tale-of-hashmaps-or-the-importance-of-reading-docs/#respond</comments>
		
		<dc:creator><![CDATA[Julián Álvarez]]></dc:creator>
		<pubDate>Mon, 19 Jul 2021 20:49:28 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[developers]]></category>
		<category><![CDATA[stories]]></category>
		<guid isPermaLink="false">https://hand-picked.io/?p=5968</guid>

					<description><![CDATA[In this article we&#8217;ll show an example of the importance of knowing about Data Structures (HashMaps or Dictionaries in this case) and paying attention to contracts and documentation, with a real story. We had an ads system (picture something like Google Ads) in an e-commerce site. And to make it simple, let&#8217;s say that we [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In this article we&#8217;ll show an example of the importance of knowing about Data Structures (HashMaps or Dictionaries in this case) and paying attention to contracts and documentation, with a real story.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img width="640" height="640" src="https://hand-picked.io/wp-content/uploads/2021/07/blog-media-ads.png" alt="Media Google Ads" class="wp-image-5973" srcset="https://hand-picked.io/wp-content/uploads/2021/07/blog-media-ads.png 640w, https://hand-picked.io/wp-content/uploads/2021/07/blog-media-ads-300x300.png 300w, https://hand-picked.io/wp-content/uploads/2021/07/blog-media-ads-150x150.png 150w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Image by <a href="https://pixabay.com/users/megan_rexazin-6742250/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=5000790" target="_blank" rel="noopener">Megan Rexazin</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=5000790" target="_blank" rel="noopener">Pixabay</a></figcaption></figure></div>



<p>We had an ads system (picture something like Google Ads) in an e-commerce site. And to make it simple, let&#8217;s say that we had 3 key endpoints:</p>



<ul><li>One to retrieve ads</li><li>Other to count impressions (a pixel request placed by the retrieved ad)</li><li>The last one to count clicks and do the proper redirect</li></ul>



<p>To count impressions, that endpoint should get an encrypted parameter, decrypt it, verify the (internal, decrypted) parameters with a signature, and then use those values impressions counting.</p>



<p>While the code that generated those links was deployed in servers that were readily updatable, the code that read those links (impressions counter) was deployed in an old monolithic system. Those servers were only deployable every 2 weeks.</p>



<ul><li>Link generator &#8211;&gt; in servers that could update</li><li>Link/impression reader &#8211;&gt; in servers that couldn&#8217;t update</li></ul>



<figure class="wp-block-image size-large"><img width="1024" height="358" src="https://hand-picked.io/wp-content/uploads/2021/07/blog-servers-1024x358.jpeg" alt="Servers Clusters" class="wp-image-5971" srcset="https://hand-picked.io/wp-content/uploads/2021/07/blog-servers-1024x358.jpeg 1024w, https://hand-picked.io/wp-content/uploads/2021/07/blog-servers-300x105.jpeg 300w, https://hand-picked.io/wp-content/uploads/2021/07/blog-servers.jpeg 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Photo by&nbsp;<strong><a href="https://www.pexels.com/@artunchained?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noopener">Manuel Geissinger</a></strong>&nbsp;from&nbsp;<strong><a href="https://www.pexels.com/photo/interior-of-office-building-325229/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noopener">Pexels</a></strong></figcaption></figure>



<p>When this code was released, both servers (clusters indeed, but let&#8217;s call them servers for simplification) were running JDK 1.5.</p>



<p>In a given moment the server which was part of the readily updatable ones, got updated to JDK 1.6, and at that point.. we lost something…</p>



<p>In the morning we were alerted by the abnormality of having 0 (zero) impressions. Fall that could not be attributed to anything organic, but a code issue.</p>



<p>So, what was happening?</p>



<h2>HashMap implementation changes</h2>



<p>Remember that I said we were creating those links with a big encrypted parameter? That had a signature mechanism that was analyzed by the impression reader server code, and if the signature (simply done by hashing) wasn&#8217;t correct, the impression was discarded.<br>So the code for the impression counter link was something like:</p>



<pre class="wp-block-code"><code>for (String key: parametersMap.keySet()) {
    appendParameter(key, parametersMap.get(key),paramsBuilder); // Appends parameter
    stringToHash += parametersMap.get(key); // append value for the string to hash to get a signature
}

// calculate the hash and add some salt
stringToHash += secret;

signature = calulateHash(stringToHash);

appendParameter("signature", signature, paramsBuilder); // Appends parameter</code></pre>



<p>On the reader/impression counter side:</p>



<pre class="wp-block-code"><code>for (String key: parametersMap.keySet()) { // before this, this code put the parameters into a Map
    stringToHash += parametersMap.get(key);
}

// calculate the hash and add some salt
stringToHash += secret;

signatureToVerify = calulateHash(stringToHash);</code></pre>



<p>Can you spot the error there? It happens that in JDK 1.6, there was a slight change in the hashing code in HashMap, which made another slight change in the order elements were placed in the internal hashtable (an array).</p>



<p>So at the point where the impression counter server did <code>.keySet</code>, it provided those keys/values in an original order (by JDK 1.5) while the new code that generated that, was delivering those values in a different order (by JDK 1.6).</p>



<figure class="wp-block-image size-large"><img width="1024" height="125" src="https://hand-picked.io/wp-content/uploads/2021/07/blog-two-hashmaps-1024x125.png" alt="Hash function comparison" class="wp-image-5970" srcset="https://hand-picked.io/wp-content/uploads/2021/07/blog-two-hashmaps-1024x125.png 1024w, https://hand-picked.io/wp-content/uploads/2021/07/blog-two-hashmaps-300x37.png 300w, https://hand-picked.io/wp-content/uploads/2021/07/blog-two-hashmaps.png 1198w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>How the HashMap#hash() function changed. (But this isn&#8217;t the exact change of this story, we just couldn&#8217;t find it)</figcaption></figure>



<p>Obviously the bug is that relying on that order from the HashMap to append and retrieve values was a violation of the HashMap contract (and Set for instance), where it is expressed that you shouldn&#8217;t rely on the HashMap keys order.</p>



<blockquote class="wp-block-quote"><p>This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.</p><cite>Extracted from the HashMap class Javadoc</cite></blockquote>



<h2>Developer&#8217;s quick solution to save the day</h2>



<p>As the server that counted those impressions wasn&#8217;t available for an update (next code upload was scheduled for the next 2 weeks!), we had to do something on the &#8216;pixel generator&#8217; with that link.</p>



<p>As the counter was expecting those parameters in a given order, we decided to use the old HashMap code, so we could get the same order to verify the signature.</p>



<p>The <code>parametersMap</code>  object ended up being an instance of the <code>HashMap15</code> class, for the sake of letting it sort those elements as the impression counter endpoint expected them to be.</p>



<h2>Cleanup and conclusion</h2>



<p>In a next release we did sort those keys before relying on the order and ditched that temporary class. (It wasn&#8217;t an elegant solution to keep).</p>



<p>So that&#8217;s the story of why we should know about data structures, contracts and reading docs… or maybe about minor bugs that could go unnoticed until big consequences happen. Have you ever had to resort to this kind of tricks to save the day and continue operations?</p>



<p><em>A Tale of Two Cities Book Cover Photo by&nbsp;<strong><a href="https://www.pexels.com/@fotios-photos?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noopener">Lisa</a></strong>&nbsp;from&nbsp;<strong><a href="https://www.pexels.com/photo/photo-of-a-tale-of-two-cities-by-charles-dickens-book-2608179/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels" target="_blank" rel="noopener">Pexels</a></strong></em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://hand-picked.io/tale-of-hashmaps-or-the-importance-of-reading-docs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
