{"id":18767,"date":"2013-11-08T22:00:54","date_gmt":"2013-11-08T20:00:54","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=18767"},"modified":"2013-11-08T11:04:15","modified_gmt":"2013-11-08T09:04:15","slug":"batch-processing-best-practices","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html","title":{"rendered":"Batch processing best practices"},"content":{"rendered":"<p>Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but there are some basic rules you need to be aware of, and I am going to enumerate the ones I found to be most important.<\/p>\n<p>From an input type point of view, the processing items may come through polling a processing item repository or by being pushed them into the system through a queue. The following diagram shows the three main components of a typical batch processing system:<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<ul>\n<li>the input component (loading items by polling or from an input queue)<\/li>\n<li>the processor: the main processing logic component<\/li>\n<li>the output component: the output channel or store where results will sent<\/li>\n<\/ul>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/11\/batch_processing_components.jpg\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-18822\" alt=\"batch_processing_components\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/11\/batch_processing_components-300x196.jpg\" width=\"300\" height=\"196\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/11\/batch_processing_components-300x196.jpg 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/11\/batch_processing_components.jpg 517w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>1. Always poll in batches<\/h2>\n<p>You should only retrieve a batch of items at a time. I have recently had to diagnose an OutOfMemoryError thrown by a scheduled job while trying to retrieve all possible items for processing.<\/p>\n<p>The system integration tests were passing as they were using small amounts of data, but when the scheduled job was offline for two days because of some deployment issue, the number of items (to be processed) had accumulated since there was no one to consume them, and when the scheduler went back online, it couldn\u2019t consume those, since they didn\u2019t fit the scheduler memory heap. So setting a high scheduling frequency rate is not enough.<\/p>\n<p>To prevent this situation you need to get only a batch of items, consume them, and then you can rerun the process until there is nothing left to process.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h2>2. Write a thread-safe batch processor<\/h2>\n<p>Typically a scheduled job should run correctly no matter how many jobs you choose to run in parallel. So the batch processor should be stateless, using only a local job execution context to pass state from one component to the other. Even tread-safe global variables are not so safe after all, since jobs\u2019 data might get mixed up on concurrent executions.<\/p>\n<h2>3. Throttling<\/h2>\n<p>When using queues (input or within the batch processor) you should always have a throttling policy. If the items producing rate is always higher than the consuming one you are heading for disaster. If the queued items are held in memory, you\u2019ll eventually run out of it. If the items are stored in a persisted queue, you\u2019ll run out of space. So, you need a mechanism of balancing the producers and consumers. As long as the producing rate is finite you just to make sure you have the right number of consumers to balance out the producing rate.<\/p>\n<p>Auto-scaling consumers like starting new ones whenever the queue size grows beyond a given threshold is a suitable adaptive strategy. Killing consumers as the queue size goes below some other threshold allows you to free unnecessary idle threads.<\/p>\n<p>The create-new-consumer threshold should be greater than the kill-idle one because if they were equal you would get a create-kill jitter when the queue size fluctuates around the threshold size.<\/p>\n<h2>4. Storing job results<\/h2>\n<p>Storing job results in memory is not very thought-out. Choosing a persistence storage (MongoDb capped collection) is a better option.<\/p>\n<p>If the results are held in memory and you forget to limit them to an upper bound, your batch processor will eventually run out of memory. Restarting the scheduler will wipe out your previous job results, and those are extremely valuable, since it\u2019s the only feedback you get.<\/p>\n<h2>5. Flooding external service providers<\/h2>\n<pre class=\" brush:java\">for(GeocodeRequest geocodeRequest : batchRequests) {\r\n   mapsService.resolveLocation(geocodeRequest);\r\n}<\/pre>\n<p>This code is flooding your map provider, since as soon as you finish a request a new one will be issued almost instantly, putting a lot of pressure on their servers. If the batchRequests number is high enough you might get banned.<\/p>\n<p>You should add a short delay between requests, but don\u2019t put your current tread to sleep, use a <a href=\"http:\/\/docs.spring.io\/spring-integration\/docs\/2.2.6.RELEASE\/reference\/html\/messaging-endpoints-chapter.html#delayer\">EIP Delayer<\/a> instead.<\/p>\n<h2>6. Use a <a href=\"http:\/\/www.eaipatterns.com\/\">EIP style programming<\/a> for your batch processor<\/h2>\n<p>While the procedural style programming is the default mind-set of most programmers, many batch processing tasks fit better on an Enterprise Integration Patterns design. All the aforementioned rules are easier to implement using EIP tools such as:<\/p>\n<ul>\n<li>message queues<\/li>\n<li>polling channels<\/li>\n<li>transformers<\/li>\n<li>splitters\/aggregators<\/li>\n<li>delayers<\/li>\n<\/ul>\n<p>Using EIP components eases testing, since you are focusing on a single responsibility at a time. The EIP components communicate through messages conveyed by queues, so changing one synchronous processing channel to a thread-pool dispatched one is just a configuration detail.<\/p>\n<p>For more about EIP you can check the excellent <a href=\"http:\/\/docs.spring.io\/spring-integration\/reference\/html\/overview.html\">Spring Integration<\/a> framework. I\u2019ve been using it for three years now, and after you get inoculated you would prefer it over procedural programming.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/vladmihalcea.wordpress.com\/2013\/10\/30\/scheduled-jobs-best-practices\/\">Batch processing best practices<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Vlad Mihalcea at the <a href=\"http:\/\/vladmihalcea.wordpress.com\/\">Vlad Mihalcea&#8217;s Blog<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but there are some basic rules you need to be aware of, and I am going to enumerate the ones I found to be most important. From an input type point of &hellip;<\/p>\n","protected":false},"author":507,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-18767","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Batch processing best practices<\/title>\n<meta name=\"description\" content=\"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Batch processing best practices\" \/>\n<meta property=\"og:description\" content=\"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/vlad.mihalcea.71\" \/>\n<meta property=\"article:published_time\" content=\"2013-11-08T20:00:54+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Vlad Mihalcea\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Vlad Mihalcea\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html\"},\"author\":{\"name\":\"Vlad Mihalcea\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/2c2d5059ee4fd88b1b3b9e52efc5b129\"},\"headline\":\"Batch processing best practices\",\"datePublished\":\"2013-11-08T20:00:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html\"},\"wordCount\":794,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html\",\"name\":\"Batch processing best practices\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2013-11-08T20:00:54+00:00\",\"description\":\"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/11\\\/batch-processing-best-practices.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Batch processing best practices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/2c2d5059ee4fd88b1b3b9e52efc5b129\",\"name\":\"Vlad Mihalcea\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g\",\"caption\":\"Vlad Mihalcea\"},\"description\":\"Vlad Mihalcea is a software architect passionate about software integration, high scalability and concurrency challenges.\",\"sameAs\":[\"http:\\\/\\\/vladmihalcea.wordpress.com\\\/\",\"https:\\\/\\\/www.facebook.com\\\/vlad.mihalcea.71\",\"http:\\\/\\\/www.linkedin.com\\\/pub\\\/vlad-mihalcea\\\/20\\\/a59\\\/580\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/vlad-mihalcea\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Batch processing best practices","description":"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html","og_locale":"en_US","og_type":"article","og_title":"Batch processing best practices","og_description":"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but","og_url":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"https:\/\/www.facebook.com\/vlad.mihalcea.71","article_published_time":"2013-11-08T20:00:54+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Vlad Mihalcea","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Vlad Mihalcea","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html"},"author":{"name":"Vlad Mihalcea","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/2c2d5059ee4fd88b1b3b9e52efc5b129"},"headline":"Batch processing best practices","datePublished":"2013-11-08T20:00:54+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html"},"wordCount":794,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html","url":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html","name":"Batch processing best practices","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2013-11-08T20:00:54+00:00","description":"Most applications have at least one batch processing task, executing a particular logic in the background. Writing a batch job is not complicated but","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/11\/batch-processing-best-practices.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Batch processing best practices"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/2c2d5059ee4fd88b1b3b9e52efc5b129","name":"Vlad Mihalcea","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f9f4ac0b2229b9f9fb993393b822ffbf63e60c1665a244176d3c4728565a9a9f?s=96&d=mm&r=g","caption":"Vlad Mihalcea"},"description":"Vlad Mihalcea is a software architect passionate about software integration, high scalability and concurrency challenges.","sameAs":["http:\/\/vladmihalcea.wordpress.com\/","https:\/\/www.facebook.com\/vlad.mihalcea.71","http:\/\/www.linkedin.com\/pub\/vlad-mihalcea\/20\/a59\/580"],"url":"https:\/\/www.javacodegeeks.com\/author\/vlad-mihalcea"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/18767","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/507"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=18767"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/18767\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=18767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=18767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=18767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}