How to ace in a Java interview

If you google “Java Interview Questions” you may find a bunch of pages. But why you still fail in your dream company’s tech interview?
Based on my 10y+ interview experience you can do preparation in this way.
  1. How to get short listed? most of the roles have a JD. Change your CV accordingly. Agencies short list candidates by those “key words” so if your CV contains those “key words” in JD, you will be short listed.
  2. Have a full knowledge of Java, Spring and its frameworks. How to define “full knowledge”, please see the below images.
  3. You can find a bunch of Java interview questions from web. However do you know what are those questions  most probably being asked in your next interview? Every time after an interview, I logged down all the questions I was asked. After 10+ years of this “hard work”, I am able to tell the frequency of each Java interview questions. For instance for year 2018, “what is hashCode” is one of the fav questions, while no one will ask “what is difference between hashtable and hashmap”
  4. Hackerrank. More and more companies started to outsource the 1st round of tech interview to hackerrank. How to prepare?
    1. get familiar with hackerrank, the more familiar the better.
    2. there is a book called <Cracking the Coding Interview>, which is really helpful.
    3. get familiar with arrays and collections in Java, as I found a lot of questions are array and collections related. For instance if you know how to “Find Pairs Sum Equal To Given Number” then you will pass atlassian’s hackerrank test.
  5. you need to at least have THREE stories in your mind. Then write them down, tell them in your own word. The story needs to be followed the STAR pattern.https://careercenter.lehigh.edu/node/145
DONE.
Now you can do your interview. If you followed all the steps I mentioned above, you will have 60% possibility to secure the role. Luck is very important in job hunting. However this is out of my control.
More details? send an email to iecaau123@mailfence.com I will send you my collections. However it may cost you 20AUD for that.
Thanks
Advertisements

Why I dislike Hackerrank!

I think hackerrank is a good place to improve your coding skills. However to my surprise a bunch of companies are using it as a door keeper for the technical interview.

How can you expect a career veteran who has a bunch of years of working experience, having knowledge from angularjs, node js to AWS and at the same time is able to resolve problems like BSF?

Personally I am a big fan of TDD(Test Driven Development) I always believe test cases can protect my implementations. But Hackerrank destroyed my belief. In hackerrank, test cases are your enemies!

Code quality? no! readable?no! testable? No(remember there is a clock in the mid of the page?! Even if I name a variable called fuckoffHackerRank is acceptable.)

I always think it is a good idea to not to stick to a problem forever. Taking a break may give you a chance to think outside of the box. This really helps me in my daily work. However Hackerrank stopped me doing this again!

These days I found Hackerrank added the below in the “thanks” email:

HackerRank only provides a platform to conduct the challenges. It does not schedule or evaluate any hiring challenges or conduct interviews for any company. Please directly contact the company that sent you the invite for such purposes.

Oh Hackerrank, why you provide such a functionality?!

@DataJpaTest fail to update

I am using H2 as my testing database.  My testing code looks like as follows:
@Test
    public void shouldBeAbleToUpdateHrUserNameByUserId(){
        final User user = userRepository.findOne(“2”);
        final String originalHrUsername = user.getHrUserName();
        final String UPDATED_HR_USERNAME = “luketong”;
        assertThat(originalHrUsername, is(ORIGINAL_HR_USERNAME));
        userRepository.updateHrUsernameBy(“2”, UPDATED_HR_USERNAME);
        final User updatedUser = userRepository.findOne(“2”);
        assertNotNull(updatedUser);
        final String updateHrUsername = updatedUser.getHrUserName();
        assertThat(updateHrUsername, is(UPDATED_HR_USERNAME));
    }
The test case failed in the last assert. I tried to debug it and to my surprise I found both updatedUser  and user point to the same memory address. If this is the case of course I can’t get the assertion passed. But the question is why they point to the same memory address?
DataJpaTest not work1
A: According to https://stackoverflow.com/questions/45617040/datajpatest-fail-to-update-in-unit-test in order to clear the underlying persistence context after executing the modifying query, you need to add an extra attribute of the annotation @Modifying as @Modifying(clearAutomatically = true)
After the change, the two user instances no longer point to the same memory address as shown below, and my test case  passed.

DataJpaTest not work2

Please be noted in my original approach, the update SQL statement is displayed in console.

AngularJS post not work

Q: AngularJS script is made (as shown below) and it is supposed to make a REST POST call to SpringBoot embeded tomcat server and then display “I am happy” dialog.

app.factory(‘voiceRecorderStatus’, function ($http) {
var o = {};
o.config = {};
o.checks = {};
o.getVoiceRecorderConfig = function () {
var dataObj = {
name: ‘abcdef’,
macAddress: ‘5006AB812A25’,
location: ‘Sydney’
};
var config = {
headers: {
‘Content-Type’: ‘application/json’
}
};

$http.post(‘http://localhost:8080/api/healthcheck&#8217;, JSON.stringify(dataObj), config)
.success(function (data, status, headers, config) {
alert(“I am happy”+ JSON.stringify(data));
})
.error(function (data, status, header, config) {
alert(“I am not happy” + data);

});

};
return o;

});

However it displays a “I am not happy” box and even does not go to the breakpoint in IntelliJ(I run the service in IntelliJ IDE) The behavior of postman is it will go to the break point of my controller.
A: right click in your Chrome browser. Hit “Inspect” it will display
2
Hit the “Console” tab it will display as :
3.png
The root cause is the No ‘Access-Control-Allow-Origin’
We can add the @CrossOrigin annotation in front of the method as shown below to resolve this problem.
@CrossOrigin
@RequestMapping(value=”/api/ping”, method=”GET”)
public ResponseEntity<String> ping(){
……
//some biz logic
……
return ResponseEntity.ok(“Hello”);
}

How to convert JSON to different objects?

Q: How to convert JSON to a complicated object? for instance List<MyObject>?
ObjectMapper mapper = new ObjectMapper();
JavaType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, MyObject.class);
List<MyObject> readValue = mapper.readValue(jsonString, collectionType);

Q: How to convert JSON to a Java object?
ObjectMapper mapper = new ObjectMapper();
MyObject myObject  = mapper.readValue(new StringReader(jsonString), MyObject.class);

Q: How to marshal a Java object to JSON?
MyObject myObject = new MyObject();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(myObject));

Q: How to convert a JSON structured String/File to JsonNode
final String filePath = “testData/amqpRequestMessages/” + fileName + “.json”;
final String jsonString = Resources.toString(Resources.getResource(filePath), UTF_8);
final JsonNode internetDmRequest = objectMapper.readTree(jsonString);

Q: How to convert a JSON File to an Object
mapper = new ObjectMapper();
final InputStream inputStream = getClass().getResourceAsStream(“/configuration/createInternet.json”);
Configuration configuration = mapper.readValue(inputStream, Configuration.class);

Q: How to convert a JSON structured String to JsonNode

import com.fasterxml.jackson.databind.JsonNode;
final String payload = “{\”data\”: {\”subscriberId\” : \”test-subscriberId\”}}”;
JsonNode payloadParams = new ObjectMapper().readTree(payload);

Q: How to convert a JSON tree to a Java object
JsonNode dataNode = ……
AccessDMRequestData accessDMRequestData = objectMapper.treeToValue(dataNode.get(“data”), AccessDMRequestData.class);

Java8 lambda expression variable

public class TrickyLambdaExpressionDemo {
public static void main(String …args){
String name = “Hello World”;
Runnable r1 = ()-> System.out.println(name);

String name1 = “”;
name1 = name.toUpperCase();
Runnable r2 = ()-> System.out.println(name1);

r1.run();
}
}

What will be the result, if you run the above code?

The answer is “Compile Error”. The error is “Variable used in Lambda expression must be effectively final”.

If you change it to

String name1 = name.toUpperCase();

Then it will print out “Hello World”

Another point we should pay attention to is the word “effectively final” what is the difference between final and effectively final?

I always think lambda expression is a kind of anonymous class. In Java any local variable within an anonymous class should be final! Thus it is reasonable lambda expression requires variable to be final. But why effectively final? it means although the developer does not put the keyword final in front of the variable, in the above sample it is name1, if once it has been initialised,  the value never changed, the variable can be treated as final. This saves developer a lot of time to avoiding put the keyword final in front of any lambda variables.

Couchbase document can be found in console but cant be found in program

Q: Couchbase document can be found in console but can’t be found in program. In console if you run the following command it will find the required document. It is working totally in the sqi env.

curl http://:8093/query/service -d ‘statement=select * from `uat` where any myorder IN orders SATISFIES myorder.id=”12345678″ END &creds=[{“user”:,”pass”:””}]’

However in the application the same statement is executed, it returns 0 result. The code looks like this:

public ServiceInventory getServiceInventoryByOrderId(final String orderId) throws ServiceInventoryException {
final String PLACEHOLDER_STATEMENT =
“select * from `” + this.bucketName + “` USE INDEX(orderid_idx) where any myorder IN orders SATISFIES myorder.id = ‘” + orderId +”‘ END”;
log.debug(“The statement we are going to execute is {}”, PLACEHOLDER_STATEMENT);

final N1qlQueryResult result = this.executeN1qlQuery(N1qlQuery.simple(PLACEHOLDER_STATEMENT));
log.info(“The size of the query result is {}”, result.allRows().size());
final List serviceInventoryList = result.allRows().stream().map(n1qlQueryRow -> {
final JsonObject document = (JsonObject) n1qlQueryRow.value().get(this.bucketName);
if (document == null) {
log.info(“Can not find anything based on {}”, this.bucketName);
}
return gsonObj.fromJson(document.toString(), ServiceInventory.class);
}).collect(Collectors.toList());

if (CollectionUtils.isEmpty(serviceInventoryList)) {
throw new ServiceInventoryException(
“Can not find a matched Service Inventory Object by orderId = ” + orderId);
}

return serviceInventoryList.get(0);

}

A:Why it is so weird? Why it is working ONLY in console?

In the method executeN1qlQuery(…) log.debug(“bucket.query time = [{}] “, System.currentTimeMillis() – startTime); can be executed, it got stuck in bucket.query(query). So what is the connection string in the bucket?
There is an assumption here, the connection String in the code is the same as the command I ran in console. But is it really the same? No. If you replace stl-nbn-cb45e-uat-cl001.np.stl.np.top.corp.telstra.com with the connection string I use in code, the execution of the command will be failed.

Postman call is successful but in code the same URL, the REST call is failed

Q: I was asked to write a REST call to a third party address service. Everything is fine but when we are trying to test it on code base level, it failed! The call to https:///v1/ failed. But it is successful in postman, how come? It is weird.

A: The service address call is a two-steps call, one is to get the token the second step is insert this token into headers and do a REST call. After investigating, I found the problem is in the headers. Below is the code:
private HttpHeaders getHttpHeaders(final String token, final String correlationId) {
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
It seems like the downstream system does not like UTF8. So if you change it to:
private HttpHeaders getHttpHeaders(final String token, final String correlationId) {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return headers;
}
The problem is resolved.

My experience in pair programming

My previous company is very famous for its pair programming, below are my thoughts

pros:
  • more efficient;
  • in conjunction with TDD, less bug;
  • easier to setup (when you are new);
  • know the whole project;
  • easy to transfer knowledge from senior to new comer;
  • as a single developer it is very easy to miss some possibility/risk for a solution, but for pair programming your pair may help you.
cons:
  • if your pair is sick (or in absence), then you can’t do anything, especially when you are new.
  • less private. I do think, especially in programming, sometimes you need to concentrate, you need to work alone; Working alone sometimes can reach higher quality;
  • Feel pressure when sb is “monitoring” you. I am not lazy just feel uncomfortable or if you can’t fix a problem you will feel pressure
  • ow to do it when we outsource a lot to India?