Writing an effective Résumé

Hello World! Hope it’s going well for you guys. As the blog title reads, this write-up is about some simple ways to make an effective resume. Personally, I have been on both the sides- the applicant as well as the interviewer. So, I can say that I have a fair idea of what would make a good resume :). The aim of this blog is to share what I think may be helpful to you guys. So, without further ado let’s start decoding easy ways to make a better resume.


I. Use a good editing tool

Let’s start with the basics ! This is the first thing that made my resume look and feel 100 times better.  Earlier I would use Microsoft word for my editing. And, psst, I sucked at it! I do not know the shortcuts to getting the right boundaries, page offsets and also getting alignments I want. (Sure, judge me all you want! :D). Then I started using online editors (such as overleaf) that allow me to build resume using Latex.

What better way than to “code” your resume ;). This trick has been so useful. Sure, it needs a little more effort than word. But, the outcome is worth the effort. It is easy to use them, they allow for anytime-anywhere access, since they store your profile online.

There are many templates available. I would say – do check them out~ .I have added my template picks in case you guys decide to give it a try (at the end of this blog). Let’s now focus on what should be the content, in the following two tricks.


II. Focus on your strengths and interests

This tricks needs your answer to two important questions. Firstly, what you are confident about and secondly how is it relevant to what you want out of this job.

One way to finding answer for these is, to write down what is it that you enjoy and are confident about along with how this can be aligned with the job requirements (the job that you are applying for).

For example – it can be programming in Python or Java or may be you have a good understanding of machine learning algorithms or you love to design new algorithms. Whatever it is, just write down on a paper first.

Then, begin to build your resume around this topic of interest. What is your relevant experience or how have you prepared for a career in it (do you have hobby projects, coursework etc), try and list them. Keep the focus around this through your resume.

Why? Because, the content on your resume to some extent dictates what you may be questioned about. So, when you focus on your strengths while adding content, it automatically translates to confidence in handling the questions thrown at you, during the course of your interview.


III. Avoid this !

I understand the urge to stand out, with your resume. I also understand the pressure of a job search. But, I cannot stress here enough that you should put things in your resume that is truly your work. It’s not too difficult for a person in the industry to identify when you blatantly lie or go overboard on exaggerating. Do not write about things that you have not done or do not understand completely. And, when you do put up impressive numbers or things you have done, you should be able to explain as to how you achieved that. Else, this simply adds unnecessary pressure when you are at the interview, in case you are asked about it.

For example, if you want to write about how you improved the reliability of a software by 15%, then you should be ready to justify how you achieved that number. Just throwing some metrics in the resume is not going to take you a long way. So, focus on what you have done and be prepared to answer how you achieved those numbers as well.


Few more good points I can think of :

  • Put your educational qualification (if experienced, add the highest level degree)
  • Keep your sentences short and effective (long sentences make the reader lose interest)
  • Put other work experience or projects that are not directly relevant to the job you are seeking in a separate section (For example – “Additional Experience“)
  • If you are sharing your resume online, you could add clickable links to your website or project pages, conference journals etc, throughout your resume
  • You could also mention about interpersonal skills (good team player etc). But, also be prepared to prove it or provide examples if needed

And finally proof read, also get it reviewed before using it !

Good luck !


Templates

Have selected two templates that you could start with, as listed below :

Template 1  Recent College graduate resume

  • contains all the information needed – fits into one page and is also not cluttered
  • The sections seem sufficient and the content is crisp

Template 2 Experienced candidate resume

  • clearly lists all the prior experience in a concise format

When you open the template with an overleaf account, it opens up the display to edit the contents. Left view has the Latex code that can be edited and the right side shows the output resume document, as in the snapshot below.

overleaf_snapshot

And, that’s all I had for this tidbit. Hope these simple tricks helped you guys make a better resume. As always let me know what you feel. You can reach me at decodergirlblog@gmail.com.

Note : This is not sponsored. Overleaf was useful to me and hence I am sharing info about it.

 

Char array versus string

Today’s tidbit is a very “basic” one. It’s about the difference between char array and string in C plus plus. If you have started with a low level language, this is a real deal ! Read on, to understand what this means. In short – the question we will try and answer today is : “Is there any difference between the two options below :”

string input= "Geekgirl"; //input is a string variable
char input[]="Geekgirl"; // input is a char array

Char Arrays

As suggested by the name char arrays are an array of “characters”. An example is as shown below. These are by default supported in C and C++. Strings are represented or implemented as char arrays that are null terminated in C language. Char arrays are hence also called the “c-strings“.

chararr
Fig 1. Char array with null terminated character  ‘\0’ (c-string)
// Usage of char arrays
//A. Declare char array
char input_text[10]; 
//Assign value via command line input
cin.getline(input_text,10);

//B. Declare char array and assign value
char input_text[]={'G','e','e','k','\0'}; 

//C. Declare and assign value using double quote enclosed literal constants
//Literal constants are by automatically null terminated (String literals)
char input_text[]="Geek";

//D. using char*
char* input_text_ptr = "Geek";

Since above are char array declarations, all rules of a regular array apply to them. They cannot be assigned a value once they have been declared.

//Once input_text is declared and assigned a value as in B and C options 
above, the following assignment operations are invalid:
input_text ="Geek"; // not allowed
input_text[]="Geek"; //not allowed
input_text ={'G','i','r','l','\0'}; // not allowed

//But, they can be edited using indexing into individual elements as below:
//valid assignments listed below.
input_text[0]="G";
input_text[1]="i";
input_text[2]="r";
input_text[3]="l";

// But, when declared using char* (pointer to character) as in case D above: :
*(input_text_ptr+0) ='D'; // not allowed. 
// But, if we allocate memory 
// and then assign a value, then we can assign char value as above:
char *input_text_ptr= (char *)malloc(sizeof(char)*size); /*Stored in heap segment*/
 *(input_text_ptr+0) = 'D'; //valid

As in case of normal arrays, the name input_text is nothing but a pointer to the start of char array: address of input_text[0].

char* temp = input_text; // using char pointer 
char temp[] = input_text; // invalid operation

//below is valid 
char temp[5]; 
temp[0]=input_text[0];
temp[1]=input_text[1];
temp[2]=input_text[2];
temp[3]=input_text[3];

String

So, what is a string in C++ then? Well, string class in C++ provides support for common string related operations such as compare, search, swap, copy and also offer dynamic sizing  , exception handling when there is access out of bounds.

Char arrays have a “fixed” size specified either implicitly or explicitly during declaration. But, strings do not require it. This is because strings are dynamically sized during runtime, where as char arrays are sized during compile time.

string mystr = "geekgirl"; // has no size or [] in the declaration
// we are creating a string object named mystr above
char mystr[] = "geekgirl"; // c style string declaration

Memory allocation

The memory for char arrays is allocated on stack unless malloc() is used to create a char array. In case malloc() is used, memory is allocated on the Heap and the user is responsible for releasing the memory after use. Since, cstrings are created with definite size in mind, it is harder to resize them, user has to be careful about invalid access. Think of String object as a utility in C++ that manages the dynamic allocations for us and provides an easier interface to perform operations on char arrays.


Passing to a function

String passing to a function is similar to how char arrays are passed, as in the example below.

char str[]="geek";
displayCharArray(str);

string str1="geek";
displayString(str1);

// passing char array to a function
void displayCharArray(char s[])
{
 cout << "Char array contains" << s <<;
}

// passing string to a function
void displayString(string s)
{
 cout << "String contains  " << s << endl;
}

Which one should one use?

In case you are implementing code to be compatible with legacy C code, then you may be better off using char arrays. String class objects are easy to use, provide features like bound check exceptions and manage the allocations – sizing and dynamic resizing, managing the free operations on the memory allocated for the user string. So, if you are using C++ and no legacy code to deal with, you could go for string objects.

As always, think of your use case and decide which one is suitable for your case. That’s all in this tidbit. There is a tiny mention about using char* in this blog (pointer to char), but will cover it in another tidbit. Until then, keep decoding!~


 

Random C things – part I

Hi There ! It’s been a while since I posted – I have just been busy with life  (read  “lazy” or occupied with random things). But, am back now.

This is not really a blog post per se. I just felt like putting up a refresher to people who are familiar with C programming. It’s in a concise question and answer format ; won’t take too long ! Go ahead … 🙂

01. Can two different type of variables be declared with same name ?


Example : int a ; and enum a { b = 2, c};

The answer to this is : Yes – if they are not in same scope (local / global scope) and variable name is not used for a “#define” constant. 

If both are in local or both are declared in global space – then there will be a clash in the symbol name space.

02. What happens to uninitialized const variable ?


It gets initialized to zero. Example : const int a; declaration will set “a” to zero and cannot be modified. Keyword “const” makes the variable a “read-only”.

Even when we use keyword “static” the variables are by default initialized to zero.

03. Can we have a structure with bit fields ? How to achieve this ?


Yes, we can!

For example :  If you want a structure that holds two variables whose values can range from 0 to 15 then , all we would need is two fields with 4 bits each. This can be achieved using a declaration as below :

struct sample{
uint8_t var1:4; // first variable 4 bits
uint8_t var2:4; // second variable 4 bits
};

04. What is structure packing?


We would want to make sure we are packing the structure variables “efficiently” – specially on embedded memory limited systems.

Example :
struct noPack{
char b; // one byte + one byte  implicit padding
uint16_t data; // two bytes
char c; // one byte + one byte implicit padding
};
a total of "6 bytes"

But, if we re-arrange this :
struct withPack{
uint16_t data; // 2 bytes
char b; // one byte
char c; // one byte
};
a total of "4 bytes" 

Yes, we saved 2 extra byte assignment just by rearranging and packing 
efficiently ! 
Usually the trick is to pack the structure starting with the biggest 
size data type (in this case (sizeof(uint16_t)) > sizeof(char)) 
to lowest size

05. What is integer overflow  ? How can we handle this ?

Yes, there can be problems when you cast a larger data type to smaller one -i.e., loss of information. Consider the example below :

uint16_t func1(uint8_t a ){
//do some operation and return
return (a+100);
}
Suppose, this function is used as below :
uint8_t temp = func1(10); // result returned is 16-bit
//but, implicitly gets truncated to 8-bit 
//(depending on the compiler's behavior)

Suppose input variable “a” was set to 0xFF  (max value for an 8-bit integer), adding a value of 100 requires more than 8 bits to hold the result of addition – resulting in an overflow when the value returned is stored in an 8 bit integer – “temp” in this example.

And, trust me when I say these can result in hard bugs to catch when they happen in production code. So, please take care of scenarios involving implicit conversions such as this ! Make sure you have fixed all the warnings your compiler spits out or at least take a look at the warning messages.

06. Why will I ever use a union?

Unions allow data members that are mutually exclusive to share memory. This is important specially in the embedded system cases where memory is a scarce resource.

For example : If you implementing protocol handler with different kinds of messages that can be exchanged, we could handle the different message types and their allocations as below on an embedded system :

// Declare a union with all types of different messages to be handled.
// All message types in the union shall share same memory.
// Only one of these messages would need to be handled by protocol implementation at 
// a given time -this means they are mutually exclusive and hence would be a good idea 
// to share the memory.

typedef union
{
  protocol_req_identity_type      identity;
  protocol_req_challenge_type     challenge;
  protocol_req_notification_type  notification;
} protocol_req_msg_union_type;

// Generic format to decipher a protocol message
// check mnessage type and cast to appropriate message type in structure.
typedef struct 
{
  protocol_msg_type_enum         msg_type; // can be a identity , challenge or a notification
  protocol_req_msg_union_type    msg_union;
}protocol_req_msg_type;

07. Why do we need Enum ?

Well! One reason I can think of is – it’s not only important that we write efficient code but also readable code. Enum(s) provide us a way to add readability to our code.

Suppose you are writing some api and want to return custom status codes -1 , 1 and 2 – to mean different return status, to the caller. We can write human readable code as below, instead of using the status codes as numbers (-1, 1 ,2) directly.

//custom verbose return codes
typedef  enum codes{
CUST_ERROR = -1,
CUST_SUCCESS = 1;
CUST_RETRY = 2;
}cust_status;

// function / api that returns a status code 
cust_status func1(){
// Do some operation and return status codes to caller
// set error as default status
cust_status status = CUST_ERROR;

//you want the user to retry later
{
//..
status = CUST_RETRY;
}
//..
{
//do some processing 
//everything went fine
status = CUST_SUCCESS;
}
//..
return status;
}

//caller checks the returned status code 
int main(){
if (CUST_SUCCESS == func1()){
printf("Success\n");
}
else if(CUST_RETRY == func1()){
printf("Retry the operation later\n");
}
}

08. What is the difference between “#define” of a constant and declaring it “const int” ?


As a novice programmer, when I started with C , I wondered why were there two options to do the same thing – which one is to be used ?

#define TEST_VARIABLE 100      // pre-processor directive
int const TEST_VARIABLE = 100; // constant variable

#define is essentially a preprocessor directive. The C preprocessor shall replace all occurrences of the given variable in the code with the value before compiler compiles the code.

Whereas const is acted upon by compiler. It only indicates that the variable is “read only” , all rules of a variable apply to it as well. But, if a compiler doesn’t optimize and replace these occurrences, then there will be an overhead.

When you don’t really care about the types  -for example : a variable that holds a fixed constant could be #defined !   Also, if you are designing in a large team : #defines may be a good option as they throw a compile error when we redefine a local variable with same name, as in the example below.

//Global variable 
int const trials =10;

int func(){
// Someone decides to use same name for a local in the function but
// you intended to use global definition at a later point.
int trials= 20; 
// defining variable "trials" with a #define would have 
// thrown an error here.

//...
// few 100 lines of code later
//...

//suppose you intended to look up the global variable "trials"
int number_trials = trials; // this has 20, not the 10 that you wanted!!
}

09.  Can I assign a pointer to constant int to a pointer to an integer ?


You can ! But, don’t !!

Example :

const int * constptr; // pointer to constant integer

int* ptr; // pointer to an integer

const int var1 =10; // constant integer

constptr = &var1; // assign a const integer (const => read only)

ptr = (int*) constptr; //valid , but don’t !

*ptr = 15; // change value pointer – run time error !!

10. Compiler and volatile qualifier in C


Compilers with optimization enabled try to make code smaller and faster based on some rules.  Volatile keyword is used to indicate to compiler to “not optimize”.

There are cases where a variable may be updated in ways unknown to the compiler – such as :

  • Memory mapped input/output – peripheral registers,
  • Modification via signal interrupt – Global modified/accessed by other functions or ISR.
  • Shared global variable in multi-threaded programming

basically, where the updates made to the variable are not in the local scope of the code block. When this keyword is not used, the variables are cached to a CPU register or optimized out by the compiler.

“Volatile” ensures that the variable reads and writes are not optimized away.Consider the example for volatile usage below :

If you have a global variable (named value_to_write) that is shared between the main program that writes value from this variable to a port and an ISR that writes to this variable. We can have three cases that will have different behavior based on compiler optimization state and volatile qualifier is used or not.

  1. No compiler optimization : In this case , the main program code is not optimized and the ISR updated value gets written to the portX in main program
  2. With compiler optimization : In this case, the compiler looks at two different code blocks, each with variable named value_to_write as shown below. Since the compiler optimization is ON, compiler looks at main code block and unable to find updates/writes to the variable “value_to_write” , decides to optimize it out. Due to this optimization, only one value gets written to portX – 0, not the one updated by the ISR, which you wanted. This now calls for “volatile” usage.
  3. With compiler optimization enabled and volatile qualifier – now, if the variable value_to_write has a qualifier called “volatile” , although the compiler does not see a write to this variable in main code segment , it does NOT optimize it out. In this case portX will have the value updated by ISR, as expected.

volatile.png

 

But, there are some things to consider before using Volatile qualifier and they are listed here. Do check this link.

Yes, each of these topics deserve a separate blog. But, that’s all for now in this blog. Keep decoding !~

Tip #1 : Customize Sublime

Hey there ! It’s been a while since I posted something. I was trying to setup Sublime editor for my work at home. Thought I will share this tip that may be useful to you guys. Sublime comes with a single file compile option for C plus plus. This could be set as default build system using option : Tools->Build System-> C++ Single File. More info on Sublime Build Systems available here

However, I wanted to setup Sublime to compile multiple Cpp files in the given folder. So, all I did was to define a custom build option :

  • Tools-> Build System- > New Build System
  • Put the commands below into a new file:

{
“cmd”: [“g++”, “${file_path}/*.cpp”, “-o”, “$file_base_name”],
“working_dir”: “$folder”,
“selector”: “source.c++”,
“shell”: true,
“variants”:
[
{
“name”: “Run”,
“cmd”: [“g++”, “${file_path}/*.cpp”, “-o”, “$file_base_name”, “&&”, “$file_path/$file_base_name”],
“working_dir”: “$folder”,
“selector”: “source.c++”,
“shell”: true
}
]
}

  • Save the file as custom.sublime-build (can be custom or any name you want)
  • Set this as the default build system under
    • Tools->Build System->custom

Once you have your multiple cpp files in your workspace folder, use :

  • Ctrl+B to compile and
  • Ctrl+shift+B to run

Do you guys know how we could modify this to compile multi folder projects? Write to me at decodergirlblog@gmail.com.

 

Life After School…

I. QWCC

Recently, I had the opportunity to be part of QWCC (Qualcomm Women Collegiate Conference) – a two day event, to serve as a mentor and also a Judge for an Hackathon. I have been wanting to write about my key take away from this event. And, finally here it is.   

QWCC’s goal is to help female freshman to senior students become more successful by providing them with pointers on development of technical and professional abilities , enabling them to build a network of peers while exposing them to industry. The event includes campus tours, lunch with the mentor , technical overviews , networking and development activities that included Hackathon.  The event had about 50 students selected from across the country. As a mentor, on day one , I had the opportunity to connect with two students – one freshman and the other a senior. This session had me answering queries they had right from engineering as a career choice to being an engineer at Qualcomm. I enjoyed the fact that the girls were uninhibited and seemed to go by the adage : No question is silly. They asked me about my project at Q, why I choose this over other projects and what’s the most interesting and challenging part in it . It seemed like they were interested in understanding what makes an engineer at Q tick at the core ! While answering their questions, it seemed to ring a bell as to what is that I have enjoyed being at work.

IMG_20170121_131245_456-mod.jpg

On day two, I was part of a unique hackathon event that had these girls divided into small groups and teamed up with young middle school girls, to come up with a prototype of an idea under one of the three areas : health care, public safety or wearables. They could use Arduino, different types of sensors to prototype the idea in about 3-4 hours. The point of this event  was to help the girls experience working in collaborative ensembles, develop leadership abilities and of course see how they utilize the technical learning and apply them to real world problems. It was pretty amazing to see these girls guide the middle school girls and involve them in the project and come up with “working” prototypes of ideas all within the allotted time. The room (pic above) was beaming with curiosity, enthusiasm and willingness to learn and explore. Many had not even worked on this platform before, they learnt it on the spot to prototype their idea. As the girls presented their prototypes and I continued with judging the event, I had begun to think about what happens to learning once we are out of school.

II. Never Stop Learning

I have always believed learning doesn’t and shouldn’t stop when we step out of school. It’s a continuous process. Isn’t the spirit of learning, exploring something that makes everyday interesting. Of course, the rewards and other desires are part of this journey, but isn’t enjoying the process the core of it? There have been innumerable articles online about how learning new things benefits our brain (ex : outlined here , based on nature journal article) and also helps as we age (npr article). There are also articles such as “how-developers-stop-learning: rise-of-the-expert-beginner” that highlight what happens particularly as a developer, when we begin work and stagnate after a certain point.  This article is an interesting read and depicts a modified Dreyfus model of skill acquisition  to show that when developer discontinues learning, he essentially ends up being an ‘expert beginner‘.

In addition, I found this article by Matthew D. Lieberman from UCLA about “Why we stop learning – paradox of Expertise. He talks about why learning ceases once people begin working and most importantly why it should not. He particularly points out that as one rises up in career, it  becomes harder for the person to let others know that he/she doesn’t know everything – that others think they know and hence becoming increasing essential that they let themselves out of this self-presentational vice. He further talks about how to deal with this and learn new things without feeling sheepish about it.  Please do give his article a read. Most importantly, as he says : “Take the time now to remind folks, including yourself, that no matter how much expertise you have, you will continue to be a learner.  If you do that, there’s a pretty good chance you will”. So, here’s hoping this blog entry serves as a gentle reminder and/ motivation to keep learning.

When we enjoy the process of learning and collaborating, working successfully in groups and achieving what you set out to, is consequential

“Live as if you were to die tomorrow. Learn as if you were to live forever.” – Mahatma Gandhi.