After upgrading my test app to Spring Boot 2.0 yesterday I decided to see how difficult the Java 9 upgrade was from there. I am happy to report that it was fairly trivial. I upgraded my maven pom to set the Java version to 9 and did a mvn clean install.
Immediately I see some no class def exceptions around javax.transaction.Transaction. I did some quick google searching and discovered the problem seems to be in the Maven Surefire plugin. I found a work around that said to set the version to 2.20.1 and added a command line flag of –add-modules javax.transaction. After doing that I was seeing errors around java.xml.bind. Doing some more searching I then added a second –add-modules java.xml.bind. This fixed the issue. In the course of doing so I found a link to the issue on apache’s website. Reading through the comments I ended up with a final configuration of 2.21.0 with the following options:
Once I dropped that configuration into my pom everything built and ran correctly. So once you get your app to Spring Boot 2.0 the jump to Java 9 is pretty seamless. My follow up change now will be to switch to the new factory methods on List and Set in the app to take full advantage of the features. Once Java 10 drops in a couple of weeks, I will take the App to 10 and see how that goes.
Ever since Java 9 was released last fall, I have been wanting to upgrade our software at work to the new platform. I am not interested in the new module stuff, mostly I just want the convenience methods like List.of(), and the platform improvements. I think G1 by default looks good, the new representation for strings to save memory looks like a huge win, and all the performance numbers that I have seen show it to be a big win. Unfortunately this is not as straight forward as one should hope.
Step 1 – Spring Support
Even though Spring 5.0 was released back in December I think which fully supports Java 9, Spring Boot 2.0 is not yet released. I believe it is in RC2 now and about to be released in the next week or so, but at this point we are less than a month away from Java 10, before we will have proper Spring Boot support in Java 9. All of our microservices are currently running on Spring Boot 1.5.10 except for one. It is still running on the 1.3.x version of Spring boot, which brings us to our second Spring issue to resolve. Some contractors that originally started that service did a hack to lazy load @Formula s in hibernate. While this worked in Hibernate 4.x in Hibernate 5 the hack no longer worked so we can’t even update this service until we refactor those entities and move that data into views. That is still a work in progress. The other microservices could be moved to 2.0 when it comes out, but I think their is a consensus that we don’t want to move to 2.0 until we have all our services to a place where we could do that.
Step 2 – Gradle
We are currently running gradle 3.5.1. Going to Java 9 is going to require Gradle 4.2 (which is also a requirement for the Spring Boot 2.0 Gradle plugin). Normally this is no big deal upgrade the gradle.build file edit the wrapper portion to the new version run ./gradlew wrapper and check in the new gradle wrapper. But in this case we still have a developer running on IntelliJ 2016.1 and another on 2016.2. They would have to upgrade to at least 2017.2 in order for the new gradle to work with their IDE. So we will need to convince the whole team to update their IDE if they haven’t already ideally at that point to 2018.1.
Step 3 – FlywayDB
We are currently using Flyway DB 4.2.0. This didn’t work with Java 9 when I was testing it, so we need to go to 5.0.x. Additionally Spring Boot 2.0 requires Flyway 5.0.x. Ideally we want to upgrade this ahead of Spring to minimize risk. Bring the new flyway into production and then once we are satisfied that it doesn’t break anything upgrade Spring Boot.
Step 4 – Docker Containers
Once we have all that software in place we then will have to update our docker containers to pull in the new JVM. It sounds like in Java 9 Linux, OpenJDK ships with an empty certificate store. So that means finding a Oracle or Azul docker container as our base. We then have to verify that New Relic works with Java 9 so we have our container monitoring. After doing all that we can update our base VM to be Java 9.
Step 5 – Update Jenkins
We will need to add a new VM to Jenkins so that as different builds switch to the new Java 9 container we also switch to compiling them with the Java 9 VM (though with the Java 8 flags still at this point).
Will the pain never end…
Finally after doing everything listed above we could change our compiler flags to 9 and start using the features. It is still a painful road to walk to get us there. At this point it feels like by the time we finish the work that needs to be done (as obviously we need to be shipping features and bug fixes, while we lay the foundation for this on the side) Java 11 will be out and we will be moving to that.
Even though Java 9 support is so close to being out in Spring Boot I still feel like I am at least 6 months away from getting to use any of it. This feels much more painful than when I moved an App from Java 7 -> 8. At that point I think it was just a matter of coordinating a JBoss container upgrade from 6.0.1 to 6.4. After we got that into production we updated the VM to Java 8 (still with everything compiling on 7). Then we upgraded our Jenkins machine to have Java 8 for the compiler, and finally we updated our maven pom to use source and target of 8. I wonder if anyone Spring shops will even make it to 9 or if everyone is holding out for 11 at this point (also to get the LTS release). While I really like the sound of the 6 month release cadence actually getting the dependencies in place and lined up to do an upgrade will probably mean most enterprises just end up going from LTS release to LTS release and I would guess that Java 9 and 10 see very little use running production code and mostly will just be things for developers to play with on their machines.
I came across this blog post today which I thought was really good. It is a deep dive into the default hashCode() implementation in java. To me the most amazing outcome of the piece is that if a given class is going to be accessed by multiple threads you really need to override hashCode otherwise biased locking is disabled. All in all it is an interesting look in the guts of the JVM and worth a read: default hashCode
Recently at work I worked on a project using Amazon AWS Lambda. This is a cool concept. Amazon calls it serverless computing, but really what it is, is abstracting the server so that you can just focus on a small task that needs to run.
In this case we had a rest endpoint that just stores some data in a database. If we think about a traditional Spring Boot Microservice we would probably do Spring Data JPA, point it at a mysql DB, and then have some rest controllers that talk to a service tier which persists the data. With Spring Boot this isn’t much code, but you still have some embedded Tomcat Server and a fair amount of ceremony for doing something very simple. After building the app you will need to deploy it to Elastic Beanstalk instance or else an EC2 Nano Instance or something similar. That is a lot of DevOps overhead to do something very simple. With Lamdba we can create a simple class that takes a pojo java object (Jackson style). With Lambda you don’t have Hibernate, you are just dealing with raw JDBC but when you are just inserting 1 Row into a Database you don’t really need am object relational mapping. You then use Amazon’s API gateway to send any requests to an endpoint to the lambda function and you are all good to go.
That got me thinking S3 now has the ability to serve an S3 bucket as a website, so you could drop an angular app into an S3 bucket and serve that up and then point it at API Gateway which then hits a Lambda and talks to an RDS instance. If your site didn’t have much traffic it would be a super cheap way to host it as Lamdba is billed based on how much compute time you use and in our case our task runs so fast I am not sure we will even break out of the free tier with all the traffic we get. You could run an entire site with no server instances provisioned which is cool. In reality I think as the app grew it would be hard to manage as separate lambda functions and you would benefit greatly from a proper framework like Spring, but for something very small and light this seems super cool. The other neat thing about Lambda is the wide language support you can use, so I wrote my Lambda in Java and my boss just made a Lambda to do some logging that was written in Node. It is a super cool concept worth checking out.
I have an update on my slowdown issues on Sierra. It appears the real problem lies in the AWS Java SDK. After talking to the spring boot people via github they were able to narrow it down to an Amazon issue. I opened an issue on github with Amazon and they responded that the version of the SDK that ships in the current spring cloud has this issue in it, and it has been fixed in a newer version of the SDK. One of the big value propositions of Spring Boot to me and the release train concept of Spring Cloud or Spring Data is that it is a collection of dependencies that have all been tested together, which lowers my risk of using them together. So I opened a request with Spring Cloud AWS to upgrade their SDK. Unfortunately they don’t seem very timely in responding to issues as I notice it looks like there are no responses on any of the issues raised in the last 2 weeks.
In the meantime I have a work around that doesn’t involve having to manually bump up your AWS SDK version and that is to set the following property in your application.properties file of your Spring Boot App:
Obviously setting this flag for your app running on AWS that uses the IAM profiles isn’t good, but it is a good local workaround on your development machine until the SDK gets updated in Spring Cloud.
Recently one of my friends was working on a Spring Boot project and he was having trouble finding an example of how to configure user login for his site with Spring Boot using JPA. I had mentioned that there is some mention of configuring security in Greg Turnquist’s book Learning Spring Boot. He had just purchased Spring Boot in Action and I don’t think he was rushing to grab another book, but he hadn’t been able to find a good online tutorial.
Today I was browsing Twitter and I came across exactly what my friend was looking for. Priyadarshini B wrote a great online tutorial on doing just that on her blog. The post was so great I wanted to share it. So head over there and check it out, you won’t be disappointed as it will walk you through the whole process.
I attended JavaMug last Wednesday as the speaker was Craig Walls author of Spring Boot in Action. When I heard about the book I had planned on purchasing it, but was disappointed there was no kindle version on Amazon. It does state if you purchase the print edition they will give you the kindle one for free, but I am trying to move away from paper books in general.
Overall the talk was pretty good. It is nice that there is a Pivotal employee local to the area so we can get a talk like this done. For most of the talk Craig just sort of demonstrated examples of what you can do with Spring Boot since there were people of varying degrees of experience with it. It was held at Improving in Addison which I had never been to, but they had some nice beer on tap (Kentucky Bourbon Barrel Ale). In a talk like this where you are just trying to introduce the concept to people it is hard to get as deep of a dive as I would like. But I did enjoy the part of the demo playing around with the metrics. That is something I haven’t really played around with, but of course got me immediately thinking about how much I would like to use that at work. I think maybe this year I will attempt to convert our legacy app to Spring Boot. It will be painful, but it just seems like more and more the benefits are so good that is what we should be doing. Hopefully I can find the time at work.
Then at the end of the talk they did a raffle and lo and behold I won the digital copy of Spring Boot in Action. I was pretty stoked about that given that I wanted that originally to begin with. When they get it to me and I get a chance to read it I will post a review up here.
I am a big fan of the work Oliver Gierke has done in Spring Data. It is a framework I use daily at work and it really is amazing. A while back Greg Turnquist had posted something on Twitter against field injection. So I asked what was wrong with field injection and he pointed me to this post that Oliver had written about it.
This post is going to be my attempt to argue against Oliver’s position on the subject. It may wind up an epic failure, but if nothing else I figured it would help me think through my thoughts and assumptions on the issue and see if I can make an argument in favor of it. First head over to Oliver’s post on the topic and read it before you continue on.
Argument 1: “It’s a null pointer begging to happen”
In Oliver’s example he MyCollaborator into MyComponent with the @Inject tag that you would use in Spring or in CDI. Then his argument is that a person would instantiate MyComponent outside of the Container with MyComponent component = new MyComponent().
My first thought is, you are dealing with a container managed component if you have @Inject in it so if someone is standing up the component outside of the container to me that already says they are doing something wrong. Given that I don’t find this a compelling argument. If you are using the component in a framework as it is designed to be used the framework will tell you if it can’t wire up the component due to missing dependencies, whether your container is Spring or it is JavaEE.
I suppose one could imagine designing a component that could be used in either Spring or CDI or standalone without a framework, and Oliver’s constructor example could still work (assuming you don’t blow up on the missing @Inject annotation which I think could happen.) So in my opinion this argument isn’t really valid or a big concern as is someone is misusing your component I am not too concerned with them getting a null pointer in that scenario.
Let’s consider his benefits of Constructor Injection. The first case is you can only create your component by providing all the dependencies. This forces the user of the component to provide everything. While I consider this a valid argument, I think the point is somewhat moot since we are talking about designing a component that already has a lifecycle to it and that a framework will inject the dependency for.
His second benefit is that you communicate mandatory requirements publicly. I have to admit I find this his most compelling argument. I don’t have a counter argument to this.
His third argument is that you can then set those fields final. I have to admit I do like making everything final so that is also a compelling argument to me. But not enough to counter the negatives of it.
Let’s consider the argument that he tries to dispel:
An often faced argument I get is: “Constructors just get too verbose if I have 6 or 7 dependencies. With fields only, this is fine”. Awesome, you’ve effectively worked around a clear indicator that the code you write is doing way too much. An increase in the number of dependencies a type has should hurt, as it makes you think about whether you should split up the component into multiple ones.
I don’t buy his counter argument here. In the project that I am working on we have a bunch of service level business logic components. We have a thin service layer that we expose to the presentation tier, and then do all the heavy lifting of our business logic in these hidden service level components. Given the high volume of business logic code we have we compose the different operations with injected reusable business logic components. This is also a huge benefit when working with a large team you get less merge conflicts as the code is spread out across more files and when you are onboarding new employees you have a lot more smaller business logic classes that are easier to digest than some massive classes with all this business logic in it.
If I split those components up that is what we have already done which is why we have to inject them all over the place to reuse those business methods. I think when dealing with a non-trivial app that is extremely large, breaking things into fine grained components that are reusable in multiple places actually leads to needing to inject more fields and not less.
Argument 2: “Testability”
In this case Oliver argues that you have to be doing reflection magic in unit tests if you use field level injection. To which I respond if you are running a dependency injection framework why wouldn’t you be using a dependency injection unit test framework. And of course we do. The answer is Mockito. With Mockito you structure your unit test like you would structure your component. So to test my service I might have something like below:
@InjectMocks final MyService service = new MyService();
final boolean result = service.methodIAmTesting();
Now I have a unit test that is structured largely like my service. The testing framework injects the mocked dependencies into our service we are testing and we wire up the results on the mocks so we can test our service. Again this strikes me as very testable as now I am writing tests that look a lot like the way my services themselves look.
So that is my argument against. Basically I think the number of arguments to the constructor actually does get extremely unreasonable in many real world scenarios where you have a lot of finely defined business logic components that can be composed in many different ways to solve the project. You do end up with a lot more boiler plate, and even if you use Lombok to hide it then you have ugly and somewhat cryptic Annotations to tell Lombok to put the @Inject annotation on the constructor. I think if you are running a dependency injection framework, it isn’t reasonable for people to instantiate those objects outside of that framework, and likewise it is very reasonable to expect your unit test framework to also be dependency injection driven.
Let me know if I have persuaded anyone to my point or if you think I am completely wrong and Oliver is right about this, I would love to hear someone explain to me why my arguments are wrong and why Oliver has been right all along, or if there is a 3rd even better way what that way is.
I may have mentioned this before, but I love going to software conferences. When I got the email mentioning that Cassandra Days was coming to Dallas with a free 1 day conference on all things Cassandra, I signed up immediately. The event was sponsored by Datastax who sells a commercial version of Cassandra called Datastax Enterprise. They had 2 tracks an introductory track for people who are just exploring Cassandra, but haven’t yet taken it to production, and track 2 which was a deeper dive for people with experience with Cassandra.
It was a great event. My team came over from the office as well and they attended a mix of track 1 and track 2. The main thing I wanted people to attend was the Data modeling sessions as that is one of the biggest changes for people who are used to SQL databases when they make the move to Cassandra. The CQL language is great to get SQL people up and running quickly, but then when they try to do things they are used to with a relational database it sort of falls apart for them. When we first signed up with Datastax Enterprise several of us got to attend their Data Modelling class on sight which was great and strongly recommended for anyone taking Cassandra into production, but my team mates had not attended those classes so this was a great event for them to attend.
I had 2 really big takeaways from the event. First was a discussion of Cassandra Light Weight Transactions. In my new Cassandra Data layer that I implemented as part of my current project I hadn’t exposed this concept yet as it is something that we haven’t used to date. It isn’t like a typical SQL transaction in that you aren’t getting the whole ACID concept or getting transactional rollback on a failure so the LWT terminology is a bit misleading. But what it does protect you is from a race condition that clobbers data. Let’s pretend you have a table where you are tracking login names. And they must be unique. If you read the table to see if a name is available and then do an insert in Cassandra there is a race condition where data can get clobbered. Imagine there are 2 users Jeffrey Haskovec and John Haskovec. They are both registering in our system at the same time. At time T1 Jeffrey Haskovec’s thread checks the table for the username of jhaskovec. There is no record so it is cleared to use it. At T2 John Haskovec’s thread then checks the table and sees that the username of jhaskovec isn’t used and so it proceeds. Then at time T3 Jeffrey Haskovec’s thread does an insert into the login table with a username of jhaskovec. The insert returns and Jeffrey thinks he has successfully registered his username. Then at T4 John Haskovec’s process inserts his username of jhaskovec which overwrites Jeffrey. At this point we aren’t aware that we just clobbered data in our datastore but when Jeffrey comes back and can’t login as his user account has been overwritten we will have a difficult to track down bug.
Enter light weight transactions. Now you change that insert statement to an insert if not exists statement in which case it starts up a transaction that guarantees it will only insert the hash if it isn’t already there. We have to check the return result of that insert statement to find out if our insert was successful. So if we go back to our previous example at T4, John Haskovec’s insert would have returned a false that it wasn’t applied and we would have avoided clobbering Jeffrey’s insert from T3. This alone is actually a problem a new table that we are modeling could have had in extremely rare situations so it was very timely that I attended this talk.
I also really liked Patrick McFadden’s advanced data modeling talk as he always gives some great ideas that are worth considering. Lots of just general things to consider there that are always helpful. One of the other talks I was at went into a bunch of cluster level configuration discussion which was also good to hear. I will dig into what we are doing and see how it compares to some of the options that were presented.
The other great thing about conferences is just networking with people. I chatted with a few other people from different companies and it is always interesting to hear how they are using Cassandra and just what things are like in their domain. All in all it was a great event and if one of them is coming to a city near you it is worth spending the day over there for a good free conference. Oh and one final cool thing was that Datastax gave us all USB drives with the latest versions of all of their software on it which is nice to play around with if you are considering rolling it out.
I attended the kegs & code last night. It was a code challenge and party with cash prizes that was hosted by Saltt Ventures. I had never attended a code challenge or hack-a-thon or anything like that, but I figured it is good to get out of your comfort zone every now and then and try something new. Plus when they have free beer that is a pretty big perk. The beer was supplied by BrainDead Brewery which I hadn’t had prior to this event. The event started out as a happy hour with pizza and beer and then at some point we setup and the challenge began. It was a race to solve 10 problems in the quickest amount of time with first place getting $500, second $250 and third $100.
I setup my laptop and opened up a new IntelliJ project to work in. Looking around I saw a whole mix of people doing different things. The one contestant that I knew Rocco was using a macbook and I suspect programming in Ruby since he is a Rails programmer. I saw someone programming on a little netbook which is funny to see as he then pulled out a huge keyboard and mouse, so his keyboard was much larger than his machine. I saw some people with Python on their screen as well. So it is pretty much pick whatever tools you are comfortable in to solve the problems. The rules that were given to us were that if you submit 10 wrong answers you are disqualified so up front you already have to be somewhat conservative and double check the questions.
The contest began and the first question displayed a sha1 hash that was a result from the word kegs with a 4 digit hexadecimal value appended to it. I quickly went out and downloaded Apache Commons Codec so I could use its DigestUtils.sha1Hex class, to spit out a hex string after you run sha1 on it. I executed my code and quickly came up with a result of c0de. The original hash presented was bdcb2013c555b6ff440a0b51ddf9c49284f48d9e
Next we were presented a json map that had integer values as a key and text as a value. You were instructed to decode it. Basically if you appended all the keys in the right order you ended up with a sentence that was the answer. Here is the original json: [[7,\" t\"],[33,\"n.\"],[14,\" B\"],[30,\"du\"],[28,\" p\"],[0,\"I \"],[23,\"te\"],[25,\" i\"],[24,\"st\"],[2,\"n'\"],[17,\"he\"],[10,\"my\"],[1,\"do\"],[26,\"t \"],[29,\"ro\"],[32,\"io\"],[19,\"I \"],[18,\"n \"],[11,\" c\"],[12,\"od\"],[15,\"ut\"],[16,\" w\"],[13,\"e.\"],[8,\"es\"],[22,\"I \"],[21,\", \"],[31,\"ct\"],[4,\"al\"],[27,\"in\"],[9,\"t \"],[6,\"ys\"],[3,\"t \"],[5,\"wa\"],[20,\"do\"]]
With this problem I considered using gson or Jackson. I haven’t actually written any gson code in over 3 years and I am used to using Jackson in the context of Spring where everything is setup for you. I quickly determined that it would take me longer to set those libs up to do the problem than to just solve it by looking at it, so I did that to move on. But I chalk that up to a lesson learned for next time on preparation for this type of event.
The next challenge we were presented with the following string: gv qrxvy V qan yevt n qrffvx V We were asked to rot13 the string and then reverse the string and replace the world girl with squirrel and then upper case that string as our answer. I googled up a rot13 algorithm that I found on stack overflow and used.
The next challenge question was a block of text:
"Ecstatic advanced and procured civility not absolute put continue. Overcame breeding or my concerns removing desirous so absolute. My melancholy unpleasing imprudence considered in advantages so impression. Almost unable put piqued talked likely houses her met. Met any nor may through resolve entered. An mr cause tried oh do shade happy.\n" +
"She travelling acceptance men unpleasant her especially entreaties law. Law forth but end any arise chief arose. Old her say learn these large. Joy fond many ham high seen this. Few preferred continual sir led incommode neglected. Discovered too old insensible collecting unpleasant but invitation.\n" +
"Savings her pleased are several started females met. Short her not among being any. Thing of judge fruit charm views do. Miles mr an forty along as he. She education get middleton day agreement performed preserved unwilling. Do however as pleased offence outward beloved by present. By outward neither he so covered amiable greater. Juvenile proposal betrayed he an informed weddings followed. Precaution day see imprudence sympathize principles. At full leaf give quit to in they up.\n" +
"Living valley had silent eat merits esteem bed. In last an or went wise as left. Visited civilly am demesne so colonel he calling. So unreserved do interested increasing sentiments. Vanity day giving points within six not law. Few impression difficulty his use has comparison decisively.\n" +
"At every tiled on ye defer do. No attention suspected oh difficult. Fond his say old meet cold find come whom. The sir park sake bred. Wonder matter now can estate esteem assure fat roused. Am performed on existence as discourse is. Pleasure friendly at marriage blessing or.\n" +
"Examine she brother prudent add day ham. Far stairs now coming bed oppose hunted become his. You zealously departure had procuring suspicion. Books whose front would purse if be do decay. Quitting you way formerly disposed perceive ladyship are. Common turned boy direct and yet.\n" +
"Way nor furnished sir procuring therefore but. Warmth far manner myself active are cannot called. Set her half end girl rich met. Me allowance departure an curiosity ye. In no talking address excited it conduct. Husbands debating replying overcame blessing he it me to domestic.\n" +
"Consider now provided laughter boy landlord dashwood. Often voice and the spoke. No shewing fertile village equally prepare up females as an. That do an case an what plan hour of paid. Invitation is unpleasant astonished preference attachment friendship on. Did sentiments increasing particular nay. Mr he recurred received prospect in. Wishing cheered parlors adapted am at amongst matters.\n" +
"Assure polite his really and others figure though. Day age advantages end sufficient eat expression travelling. Of on am father by agreed supply rather either. Own handsome delicate its property mistress her end appetite. Mean are sons too sold nor said. Son share three men power boy you. Now merits wonder effect garret own.";
We were instructed to count the number of words in the block of text that only used letters from the first half of the alphabet. For this problem I found myself wishing I was better with Java 8 Lambas and Streams as this seemed like a perfect problem to stream through the test and then do reductions until we are left with what we want to count. However since I am still a beginner on the Java 8 functional style I slammed out the traditional imperative style. I split the block of text into words. I iterated the array of words and converted them to lower case and then iterated through each letter. I took advantage of the fact that a char in Java is a 16 bit unsigned integer. I found the ascii value for the letter m which is 109 (for lowercase) and then said if the value of the char was > 109 then we break out of the loop and don’t count the word otherwise we increment the count. That worked great and it was on to the next challenge.
I had actually forgotten about this question until just now when I am reviewing my code from the event. This question was given a list of numbers convert them all to binary and count how many one’s there are in those binary numbers. Then take that count and convert that number to binary and that is the answer. The numbers we had to convert were as follows: 533, 239, 1144, 51, 217, 247, 312, 0, 941, 1060, 805, 158, 1020, 1038, 748, 834, 36, 460, 688, 276, 2, 112, 91, 297, 954, 245, 885, 37, 1120, 803, 551, 257, 654, 1101, 948, 1050, 524, 607, 336, 883, 17, 524, 66, 399, 343, 368, 389, 741, 841, 196, 303, 20, 190, 828, 940, 825, 941, 258, 385, 14, 650, 427, 118, 44, 152, 709, 112, 554, 183, 22, 711, 772, 865, 986, 399, 957, 358, 759, 306, 94, 577, 980, 396, 451, 441, 829, 145, 62, 566, 138, 899, 1010, 383, 449, 745, 560, 586, 489, 117, 56, 508 For this problem I just slammed all the numbers into an array iterated the array and appended the binary value to a StringBuilder using Integer.toBinaryString(). Then I went character by character through the string builder and counted the ones.
The next challenge was to count the number of numbers between 0 and 10^8 that divide evenly by 13 and also if you reverse the number the reversed number also divided by 13 evenly. So for example if 1234 divided evenly by 13 check if 4321 also divided evenly by 13, and if so count it. This was a pretty easy problem to solve basically iterate in a loop and do a couple of modulus operations.
Then I hit the next question. It was a database table of 20 ids and values. You were presented a db query that was something like SELECT SUM(VALUE) FROM TABLE WHERE value / key > 20 AND value / 2 NOT EQUAL 0. I quickly wrote up some java to do the algorithm and slammed the values into a map and spun there and did the result. I got the result of 1620 and I entered it and was told it was incorrect. I double and triple checked both my values and my algorithm and they looked correct. So I loaded all the data into a SQLServer database that I have on my laptop. I again got the same result 1620 which they said was incorrect. At that point I was basically blocked as I had printed out all the values at each step in the java program and could verify it was doing the right thing. After banging my head on this problem for probably 15 minutes then all the money prizes were taken. They offered to give me the value if I wanted to complete the rest of the challenges, but my thought was if I was out of the money I would rather grab a beer and chat with some people, so that is what I did. I ended up completing 60% of the challenge and had a lot of fun messing around with it.
I was discussing the problems with Rocco afterwards (whom placed 2nd). He said there was also a question about pulling something out of an Amazon S3 which I haven’t done, so that would have taken a bit of research but was probably something I could quickly google. The winner of the challenge interestingly enough actually got more than 10 wrong answers. By the rules we were given at the start of the contest he should have been disqualified but they changed the rules in the middle and said they were going to allow 25 incorrect answers. Rocco said the winner beat him by about 5 minutes.
Would I do it again? For sure, however I think before the next one I would do a little prep. First I would have a new IntelliJ project setup and just preload common libraries you are probably going to need to solve most problems. So next time I will have a bunch of things like Apache Commons downloaded and ready to go and some JSON library as well that I will have practiced with. A question worth asking is would I have an advantage programming in a more dynamic language than Java? I think if you have the advantage of a great IDE like Idea and you had a preloaded project with most common libs you are going to need for anything like this type of challenge I don’t feel you are at a disadvantage using Java. One of the biggest strengths of Java is just how rich the libraries are that you can solve most of these things with very few lines of code. Maybe if I had access to the Java 9 REPL shell it could be faster, but coding inside of my IDE is very fast. I saw some people brought external keyboards and mice. I type fast enough on my laptop I can’t see bringing an external keyboard, but I will definitely bring an external mouse next time I could speed things up with that.