Author Archives: admin

Interviewing and Being Interviewed

For the past 2 months, I have been interviewing candidates for 3 different positions: Business Analyst, Test Engineer, and Software Developer. The candidates that I interview are first vetted by headhunters, then their resumes are reviewed by me for specific job skills. If they pass those two checks, I act as gatekeeper and perform an initial interview to determine whether they will be considered for the job. This process means I’m not interviewing the candidates who have no matching skills.  But there is still a great difference between the candidates.

My questions tend to focus on 3 areas for each interview: what experience can you show me that matches the qualifications I’m trying to meet, how do you handle difficult and/or complex situations on the job and what job specific knowledge do you possess.

Headhunters have seen the same job listing that I’m working from when I interview a candidate. So I’m always surprised when that candidate has no experience in one of those job areas. Mind you, I will hopefully catch that when I review the resume, if the headhunter hasn’t. But I will sometimes give the candidate the benefit of the doubt if I see similar items listed on their resume. But, if I then talk to the candidate and they have no experience in that area, I see this as a waste of time, both for me and for the candidate, since they are not someone I can consider hiring.

The knowledge I’m looking for is more the book learning – type of information; the type of things you learn in school and let you communicate with like-minded professionals. We all hate the tech-speak of others. But we have all learned that the tech-speak helps us communicate effectively with like-minded individuals. If you don’t know what a tool is that is common to your profession, or you don’t understand a term I use that is in wide application within your profession, I will not look favorably upon your candidacy.

I do have a pet peeve for this one. I am a technical person. I am frustrated when the person I’m interviewing talks to me as if I do not have that background, but rather as they would talk to an ‘outsider’, someone with no technical skills. Sometimes I thinks it’s because they don’t understand the concept well enough to explain it. Sometimes I think it’s because they’re not used to ‘talking tech’. Frankly, they need to get over that.

Lastly, I will as ‘what if’ type scenarios. If the person has experience with those, I want to hear how they were handled. If they don’t, I want to hear the logical thought process they would go through to come up with a solution.  If they have been through the given scenario before, I will often try to come up with others so I can see how they’ll handle a ‘new’ situation. If they have been through the situation before, I want details. This is their place to shine because they are showing how they overcame a difficult situation. I was using checkmarks for the job skills. I will be looking for how much you understand a situation and can relay the solution for this question.

Many times, an answer may be good for several questions. For example, a ‘what if’ may also help me see that the person has the technical vocabulary I’m looking for, or that they have had the experience that the job requirements asks for. Hopefully I won’t then ask a question that requires a person to repeat themselves.

It’s interesting that I have seen, after many, many interviews, that there are certain personality types that make a good interviewee for each position. For the analyst, I want a people person, for the tester, I want a very detailed person and for the developer, I want someone who can get ‘into the weeds’ when it comes to technical matters.

The analyst needs to have both technical knowledge and people skills. They are primarily involved in helping to articulate the requirements from the stakeholders and convert those into a technical solution. For this, they need to be able to talk to people. The candidate that I find that does best then is the one that I can hold a conversation with. They will easily elaborate on any answer. They will be perceptive enough to see the point of my question and be sure to hit that point with their answer. They will understand the ‘big picture’ and their questions to me at the end will show that.

The tester better be detail oriented. Their job is to find problems with a project before the stakeholder, or the end user, does. If something slips through, they are often the ones that are blamed. When I talk to this person, I expect steps 1 to 3 of their explanation will have several subparts. I will not need to ask them to elaborate because they have probably given me more information that I expected.

The developer may be the person with less people skills than the others. Often they are the person who I need to ask many follow up questions to get answers. But, when I ask those follow-up questions, it is often of a technical nature and I expect a technical response. I want you to explain to me how your thought processes worked. I want you to help me understand where the difficulty lay and how you resolved it. I want to know that you can do better than the monkey in front of the keyboard writing Shakespeare. I want you to show me you understand why a certain technology you use is the better choice for the problem given.

Many of the candidates I interview do not speak English as their first language. Practically speaking, that means I’m dealing with an accent. For this reason, I try to conduct video interviews whenever possible. That way, I can read lips to help me understand what they are saying. Video interviews also help me see the person’s body language as they speak. Are they confident? Are they struggling to answer my questions? Are they expressing a passion for their chosen profession?

The down side of any remote interview – video or voice only – is the person with the lousy connection or the poor equipment. Please people! This is a technical job that I’m interviewing you for. If you can’t figure out how to connect, or how to be heard, I will think less of your problem solving abilities. The current positions are remote, which means you’ll spend a lot of time in video or voice conferences. The others on the call with you will not put up with this nonsense!

The best interviews? When I interview someone with ‘that spark’. They are passionate about what they do. They are perceptive in their answers. They are engaging.

The frustrating interviews? When I interview a great person, who is not great for the position for which I’m seeking candidates. I wish I could put you in my pocket to pull out at a later date. But I know that you’re good enough that you’ll have had several great offers before I can talk with you again.

 

Calling AWS Lambda from PHP

Amazon Web Services (AWS) documentation is voluminous. Some of it’s good; some of it’s bad. And sometimes you have to look carefully to figure out that what you’re viewing is outdated.

Thus it was when I tried to figure out how to call a Lambda service from PHP.

I had created a web service in Java that was being deployed to AWS Lambda. We had connected it to an AWS API Gateway, figuring that a web service call to the API Gateway would be the easiest way to implement a client. Not so. Not in PHP at least.

I got the service working so that I could call it from Postman. But, when I tried calling it using PHP’s cURL library, I found that trying to calculate the signature required to pass the AWS Secret Key was a headache on good days, and would drive you to drink on bad. I can’t tell you why what I tried didn’t work. I only know that I kept getting Missing Authorization errors that I couldn’t overcome and still stay sane.

So I switched to using the AWS PHP library which, I guess, I should have used in the first place. But the documentation required numerous gotos that made it confusing to follow. There were no simple examples. There were no straightforward “here’s how it should look” instructions to follow. Eventually, however, I put the pieces together. And, hopefully, you can, too.

Starting with one example, I first worked out how to get the LambdaClient object I needed.

The first task was to get the credential information. Those who have developed for AWS on their own machines may have noticed that this information is stored in an .aws subdirectory under the user’s folders. The common way of retrieving the key and secret assume access to this subdirectory. The second way this is done assumes system variables with the values. My implementation could not make use of this method. So AWS allows for custom credential objects, which is what I used:

public function getCredentials() {
   return function () {
      // Get the credential variables
      $key = AWS_KEY;
      $secret = AWS_SECRET;
      if ($key && $secret) {
         write_log('credentials created');
         return Promise\promise_for(
            new Credentials($key, $secret)
         );
      }

      $msg = 'Could not find credential variables. ';
      return new RejectedPromise(new CredentialsException($msg));
   };
}

Since this is part of a WordPress site, the AWS_ variables are stored in the wp_config file.

The documentation recommends starting with an instance of the Aws\Sdk, then creating the client from there:

$sdk = new Aws\Sdk([
   'region' => REGION,
   'version' => 'latest',
   'credentials' => $this->getCredentials()
]);
$client = $sdk->createLambda();

… where $this->getCredentials() uses the function above.

Odd thing, though, is even after creating the client included passing credentials and location information, that was needed again when we actually made the call to the server. So I set up another function to hold that information:

public function config(){
   $config = array(
      'credentials' => array(
         'key'    => AWS_KEY,
         'secret' => AWS_SECRET,
      ),
      'region'  => AWS_REGION,
      'version' => "2015-03-31"
   );

   write_log('lambda config: ' . json_encode($config));
   return $config;
}

Yes, I know I was inconsistent with the versions. But, for this, I wanted to make sure I was using what I had programmed to, to ensure nothing broke later.

Last step was the actual call to Lambda:

public function sendMessage() {
   $client         = $this->getLambdaClient();
   $json_config = json_encode($this->config());

   $result = $client->invoke([
      'ClientContext' => base64_encode($json_config),
      'InvocationType' => 'RequestResponse',
      'FunctionName' => FUNCTION_NAME,
      'LogType' => 'Tail',
      'Payload' => json_encode($my_input)
   ]);

   write_log( $result);
   $log_unencode = base64_decode($result->get('LogResult'));
   write_log("unencoded log: " . $log_unencode);
   write_log("returned payload: " . $result->get('Payload'));

   return $result->get('Payload');
}

Interesting thing was needing to encode the configuration. Makes sense, I guess, since it’s sending login information. But that wasn’t required when creating the client object.

Also note the fact that the Payload needed to be in JSON format to be sent.

The result object that I wrote to the log was interesting to see. It didn’t include the Payload, which I thought was weird. So at first, not knowing how to get the results, I tried pulling the Cloudwatch log back to see whether I could get the results that way, since I was printing them in the log. Interestingly enough, the log was base64 encoded and had to be decoded to read.

But after printing the $result->get(‘Payload’)), I was able to find the results of the call.

This is a slow call. I’m assuming that’s because this is an ‘on demand’ service. But we will be making several of these at a time so I’m hoping the successive ones will be faster.

Using JdbcTemplate in Spring Boot to Insert a Record and Return a ID

There is more than one way to skin a cat (pardon to my cats). In fact, to insert a record into a database within Spring Boot, I found at least 6 ways:

  • StoredProcedureQuery
  • Prepared Statements (with various flavors)
  • Callable Statements (with various flavors)
  • JdbcTemplates
  • JdbcTemplates with Prepared Statements
  • JdbcTemplates with Callable Statements

There were probably more. But I didn’t save my search history to find them all again.

I have an unique situation in which I’m working. The database on the backend is Microsoft SQL Server. The insert statement is using a Stored Procedure. And the stored procedure is returning the record id by calling @@IDENTITY itself.

Oftentimes, when one is working with MSSQL, one is working with the entire Microsoft stack, which includes some flavor of .Net. But the client wanted to have all their middleware code standardized to Spring Boot. Not a big deal, except for the fact that there were existing Stored Procedures to work with, not the database tables directly.

This has provided a few unique challenges. Rather than using Spring Boot’s ready-made method for automatically creating models for databases, the models had to be created by hand. And I learned early on that, when using StoredProcedureQuery, ‘column names’ wouldn’t work: the parameters had to be entered in the order expected by the stored procedure, and indices used instead.

That last item took a day to figure out.This latest issue took just about as long. And hopefully, some poor soul will find this post to aid in their quest for the same information.

That problem was inserting a record and returning the new id for that record. The first problem was dealing with null values. StoredProcedureQuery had been infinitely useful when running stored procedures that extracted data. It became almost cookie cutter to create the code:

StoredProcedureQuery query = [EntityManager].createStoredProcedureQuery("[stored procedure name]", [Model class].class);
query.registerStoredProcedureParameter([index], [typeclass].class, ParameterMode.IN [or] ParameterMode.OUT);
query.setParameter([index],[value]);
return query.getSingleResult(); [or] return query.getResultList();

But this wouldn’t work for inserts. Initially, my problem with inserts was that they could contain null values. StoredProcedureQuery didn’t like null values. And, after much research and trial and error, I found that JdbcTemplate was my friend. By using JdbcTemplate, I could add null parameters and the code wouldn’t choke on me. Problem was, JdbcTemplate.update, which I was using, would return the number of records affected, but not the new ID, if a record was being inserted. Thus began my long search for something else that would work.

The popular response in Stack Overflow was to use:


KeyHolder holder = new GeneratedKeyHolder();

I couldn’t make that work. I’d get errors because ‘nothing’ was being returned.

I checked all the other options on JdbcTemplate, since that still seemed my best option for accomplishing this (since I might have nulls in the insert parameters). I literally would check the documentation for each option, then Google to see how they were used.

I finally came across the documentation for CallableStatement. It is passed as a parameter in a call from JdbcTemplate, so my null values could be handled. And it allowed a return value to be ‘registered’ for retrieval. That is, since I was not retrieving a value with a column or variable name, I could set one in order to find the value after the call had been made.

My thanks to these two sources to helping me out:

http://www.java2s.com/Code/Java/Spring/ImplementsCallableStatementCreator.htm
http://forum.spring.io/forum/spring-projects/data/239-jdbctemplate-call-example

Here’s the basic syntax that I ended up using:


import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java util.Map;

import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;

// note: I did have to list all my input and output parameter types, unlike in
// the examples where the list only included the output type
List out = new ArrayList();
out.add(new SqlParameter(1, Types.NVARCHAR));
out.add(new SqlParameter(2, Types.INTEGER));
out.add(new SqlOutParameter(“id”,Types.NUMERIC));

Map<String, Object> returnList
= getJdbcTemplate().call(new MyCallableStatementCreator(params), out);

…..

class MyCallableStatementCreator implements CallableStatementCreator {

private ParamModel params;

public MyCallableStatementCreator(ParamModel param) {
this.params = params;
}
@Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
// note: I received an error until I put the brackets around the call, and the word ‘call’ was required
CallableStatement stmt = con.prepareCall(“{call my_stored_procedure(?,?,?) }”);

stmt.setString(1,params.getFirstVal());
stmt.setInt(2, params.getSecondVal());
stmt.registerOutParameter(3, Types.INTEGER);
return stmt;
}