Software Engineer Job Description

Software Engineer Job Description

There was an article I read in the news lately about the top 7 careers in Utah. Number three in the list was a software developer or software engineer. The terms have slightly different meaning, but can be interchanged quite frequently. Quite often I have either been asked what to include in a my company’s software engineer job description when we are looking to hire new engineers, or I have been looking for jobs and had to sift through tons of different qualification requirements. It seems every company has a different idea of what is a software engineer in their job description. Although it is perfectly ok to have specific requirements, we should broaden the scope a little bit. If an engineer is good at problem solving, debugging, and looking through other’s then the engineer should be considered for a position even if he or she is not familiar with the technologies that make up the specific company’s stack.



GOOD software engineer description

  • CAN CODE: Obviously you need someone who can code. The best way is to have a person either code or sudo code during an interview. Have the potential candidate go to a white board and solve some problem of your choice. Some common examples are to have the engineer code a binary search or code a method to detect a palindrome.
  • UNDERSTAND DATA STRUCTURES: Knowing different data structures like trees, lists, sets, and maps is essential. Every type of data structure has a specific purpose. These are just more tools inside an engineers tool belt.
  • KNOW DESIGN PATTERNS: The world of software has lots complexities in it. A software engineer should know several different design patterns. These patterns are like tools in an engineers tool belt. Each tool should do one job and do it really well. Some examples of design patterns are understanding singletons, command patterns, rest, or dependency injection. These are independent of any language.
  • DEBUG CODE: This is an absolute must in any software engineer. Using tools such as debug mode in an IDE or how to use programs like gdb are essential. Code will always have bugs, and being able find, troubleshoot, and fix bugs is essential. You could always present some code to the engineer with a bug and ask him or her to figure out what is wrong and give a possible solution.
  • SOLVE PROBLEMS: Any features that a company or customers need often include complex problem solving. For example how to persist data based on what is need more, writing or reading? What is the best solution to the problem?
  • UNDERSTAND COMPLEXITY: Knowing every algorithm and its big O complexity is overrated. More important is being able to derive big O complexity. Have the engineer determine what the big O complexity of some provided method.
  • DESIGN STRUCTURES: If your stack uses OOP (Object Oriented Programming), functional (i.e. javascript or c), or embedded paradigms then the engineer should have some familiarity with them. A kernel developer, for example, needs to understand good functional programming designs more than object oriented designs.
  • WHAT DON’T I KNOW: Most software engineers do not know the answers to every question. Being able to know what to search for on google is important. Example: If you are in angular land you need to know how to speak the angular language. Searching should use things like directives or scope.
  • STAYS MODERN: Software is a fast moving field. If an engineer does not stay current he or she falls behind fast. A prime example is knowing only perl or php. Most software stacks have moved towards some rest server like java or node and a frontend in angular. While there are so many technologies out there knowing specifics can be hard, but an engineer should be familiar enough with what various technologies to know if they will be a solution to specific problems that arise.
  • KNOWS MATH: Knowing how to implement a mathematical function – such as a simple Riemann sum – is what separates a junior or entry level position from a senior or architect level position. You could always provide a mathematical equation and have the engineer give sudo code of how to translate the idea into code.

BAD software engineer description

  • SPECIFIC LANGUAGE: I have had interviews that ask very specific questions to a programming language. They reference obscure aspects of a language that nobody will need on a regular basis. Being able to google an answer is more important than knowing specifics.
  • SPECIFIC APPLICATIONS: While this should be determined on a case by case basis, having requirements like knowing specific applications should generally be avoided. Example: requiring a software developer to know protractor for end to end testing. This still uses selenium under the hood and has all the same selenium problems that any other end to end testing framework will have.
  • LIMITING TO DEGREES: Having a degree is always beneficial. Especially from colleges or universities that have abet accreditations. I have mixed feelings on this subject. Some self taught engineers are so thirsty to know in depth how to program, but some learn just enough to get by and have gaps in their knowledge.
  • TAKE HOME CODE TESTS: These are terrible because the user can easily have someone else code the solution. If you need to give them a take home test to assess the engineer’s ability to program, then you should add bugs to the code and have the engineer debug the code in real time during an interview.
  • NOT ALLOWING SEARCHING: There have been interviews I have had where I have been required to take some test without being able to use google. Being able to know what to search for in order to solve a problem is 100% essential to a good engineer.




Benefits

The number of jobs that require software to be made is only going to increase. The number of people with mobile computing platforms (iphones or android phones) is very prevalent. A company needs to not only have a competitive salary, but have other benefits or perks to attract top talent. Some companies provide 20 days paid vacation in the first year along with catered meals and great health benefits. Having good benefits will give the company a bigger pool of candidates to select.

Conclusion

Hopefully this helps define a good software engineer job description. These are things a company should look for and not look for in potential software engineering candidates.

Custom PS2 Keyboard GPIO for Spartan 6 Microblaze

Description

This is an old post I never finished. I just thought I would at least share the code for the project. I made a keyboard interface with PS2 that plugged into the Spartan 6 Microblaze. You will need to make sure you have the right voltage and resistors in the right place. There is also a wire for the clock and data. PS2 is a pretty old standard and there are a lot of diagrams out there for it.



VHDL

user_logic.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library proc_common_v3_00_a;
use proc_common_v3_00_a.proc_common_pkg.all;

-- DO NOT EDIT ABOVE THIS LINE --------------------

--USER libraries added here

------------------------------------------------------------------------------
-- Entity section
------------------------------------------------------------------------------
-- Definition of Generics:
--   C_NUM_REG                    -- Number of software accessible registers
--   C_SLV_DWIDTH                 -- Slave interface data bus width
--
-- Definition of Ports:
--   Bus2IP_Clk                   -- Bus to IP clock
--   Bus2IP_Resetn                -- Bus to IP reset
--   Bus2IP_Data                  -- Bus to IP data bus
--   Bus2IP_BE                    -- Bus to IP byte enables
--   Bus2IP_RdCE                  -- Bus to IP read chip enable
--   Bus2IP_WrCE                  -- Bus to IP write chip enable
--   IP2Bus_Data                  -- IP to Bus data bus
--   IP2Bus_RdAck                 -- IP to Bus read transfer acknowledgement
--   IP2Bus_WrAck                 -- IP to Bus write transfer acknowledgement
--   IP2Bus_Error                 -- IP to Bus error response
------------------------------------------------------------------------------

entity user_logic is
  generic
  (
    -- ADD USER GENERICS BELOW THIS LINE ---------------
    --USER generics added here
    -- ADD USER GENERICS ABOVE THIS LINE ---------------

    -- DO NOT EDIT BELOW THIS LINE ---------------------
    -- Bus protocol parameters, do not add to or delete
    C_NUM_REG                      : integer              := 4;
    C_SLV_DWIDTH                   : integer              := 32
    -- DO NOT EDIT ABOVE THIS LINE ---------------------
  );
  port
  (
    -- ADD USER PORTS BELOW THIS LINE ------------------
    
	 --USER ports added here
--	 clk, rst : in std_logic;
		ps2d, ps2c : in std_logic;
--		rx_en : in std_logic;
--		rx_done_tick : out std_logic;
		shift_en : out std_logic;
		dout : out std_logic_vector(7 downto 0);
		myinterrupt : out std_logic;
		
    -- ADD USER PORTS ABOVE THIS LINE ------------------

    -- DO NOT EDIT BELOW THIS LINE ---------------------
    -- Bus protocol ports, do not add to or delete
    Bus2IP_Clk                     : in  std_logic;
    Bus2IP_Resetn                  : in  std_logic;
    Bus2IP_Data                    : in  std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    Bus2IP_BE                      : in  std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
    Bus2IP_RdCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    Bus2IP_WrCE                    : in  std_logic_vector(C_NUM_REG-1 downto 0);
    IP2Bus_Data                    : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
    IP2Bus_RdAck                   : out std_logic;
    IP2Bus_WrAck                   : out std_logic;
    IP2Bus_Error                   : out std_logic
    -- DO NOT EDIT ABOVE THIS LINE ---------------------
  );

  attribute MAX_FANOUT : string;
  attribute SIGIS : string;

  attribute SIGIS of Bus2IP_Clk    : signal is "CLK";
  attribute SIGIS of Bus2IP_Resetn : signal is "RST";

end entity user_logic;

------------------------------------------------------------------------------
-- Architecture section
------------------------------------------------------------------------------

architecture IMP of user_logic is

  --USER signal declarations added here, as needed for user logic
	type statetype is (idle, dps, load);
	signal state_reg, state_next : statetype;
	-- filter
	signal filter_reg, filter_next : std_logic_vector(7 downto 0);
	signal f_ps2c_reg, f_ps2c_next : std_logic;

	signal b_reg, b_next : std_logic_vector(10 downto 0);
	signal n_reg, n_next : unsigned(3 downto 0);
	signal shift_reg, shift_next : std_logic := '0';
	
	signal fall_edge : std_logic;
	signal end_buff : std_logic;
--	signal rx_en : std_logic;
	signal zeros : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
	
  ------------------------------------------
  -- Signals for user logic slave model s/w accessible register example
  ------------------------------------------
  signal slv_reg0                       : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
  signal slv_reg1                       : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
  signal slv_reg2                       : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
  signal slv_reg3                       : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
  signal slv_reg_write_sel              : std_logic_vector(3 downto 0);
  signal slv_reg_read_sel               : std_logic_vector(3 downto 0);
  signal slv_ip2bus_data                : std_logic_vector(C_SLV_DWIDTH-1 downto 0);
  signal slv_read_ack                   : std_logic;
  signal slv_write_ack                  : std_logic;

begin

  --USER logic implementation added here

-- filter 
process (Bus2IP_Clk, Bus2IP_Resetn) 
begin
  if (Bus2IP_Resetn = '0') then
    filter_reg <= (others => '0');
    f_ps2c_reg <= '0';
  elsif (Bus2IP_Clk'event and Bus2IP_Clk='1') then
    filter_reg <= filter_next;
    f_ps2c_reg <= f_ps2c_next;
  end if;
end process;


filter_next <= ps2c & filter_reg(7 downto 1);
f_ps2c_next <= '1' when filter_reg = "11111111" else
               '0' when filter_reg = "00000000" else
               f_ps2c_reg;

fall_edge <= f_ps2c_reg and (not f_ps2c_next);

-- rx_en will need to be set to 1 always by this design
--rx_en <= '1';
zeros <= (others => '0');

-- registers
process (Bus2IP_Clk, Bus2IP_Resetn)
begin
	if (Bus2IP_Resetn = '0') then
		state_reg <= idle;
		n_reg <= (others => '0');
		b_reg <= (others => '0');
		slv_reg0 <= (others => '0');
	elsif (Bus2IP_Clk'event and Bus2IP_Clk='1') then
		state_reg <= state_next;
		n_reg <= n_next;
		b_reg <= b_next;
		shift_reg <= shift_reg;
		slv_reg0 <= zeros or  b_reg(8 downto 1);
	end if;
end process;

-- next-state logic
process(state_reg, n_reg, b_reg, fall_edge, ps2d)

begin
	myinterrupt <= '0';
	--rx_done_tick <= '0';
	state_next <= state_reg;
	n_next <= n_reg;
	b_next <= b_reg;
  
  case state_reg is 
    when idle =>
--      myinterrupt <= '1';
      if (fall_edge = '1') then 
        --shift in start bit
        b_next <= ps2d & b_reg(10 downto 1);
        n_next <= "1001"; -- set count to 8 again
        state_next <= dps;
      end if;
    when dps => 
 --     myinterrupt <= '0';
      if (fall_edge = '1' ) then
        b_next <= ps2d & b_reg(10 downto 1);
        if (n_reg = 0) then 
          state_next <= load;
        else 
          n_next <= n_reg - 1;
        end if;
      end if;
    when load =>
		-- here we handle if signal f0 and following signal are 
		-- asserted - we don't want to transmit them to dout.
      -- one more state to complete last shift
		state_next <= idle;
--		rx_done_tick <= '1';
		myinterrupt <= '1';
		if (b_reg(8 downto 0) = x"12" or b_reg(8 downto 0) = x"59") then
			shift_next <= not shift_reg;
			if (shift_reg = '1') then
--				rx_done_tick <= '0';
				myinterrupt <= '0';
			end if;
		elsif (b_reg(8 downto 0) = "11110000") then
			end_buff <= '1';
--			rx_done_tick <= '0';
			myinterrupt <= '0';
		elsif (end_buff = '1') then
			end_buff <= '0';	
--			rx_done_tick <= '0';
			myinterrupt <= '0';
		end if;
  end case;
end process;

shift_en <= shift_reg;
dout <= b_reg(8 downto 1);

  slv_reg_write_sel <= Bus2IP_WrCE(3 downto 0);
  slv_reg_read_sel  <= Bus2IP_RdCE(3 downto 0);
  slv_write_ack     <= Bus2IP_WrCE(0) or Bus2IP_WrCE(1) or Bus2IP_WrCE(2) or Bus2IP_WrCE(3);
  slv_read_ack      <= Bus2IP_RdCE(0) or Bus2IP_RdCE(1) or Bus2IP_RdCE(2) or Bus2IP_RdCE(3);


  -- implement slave model software accessible register(s) read mux
  SLAVE_REG_READ_PROC : process( slv_reg_read_sel, slv_reg0, slv_reg1, slv_reg2, slv_reg3 ) is
  begin

    case slv_reg_read_sel is
      when "1000" => slv_ip2bus_data <= slv_reg0;
      when "0100" => slv_ip2bus_data <= slv_reg1;
      when "0010" => slv_ip2bus_data <= slv_reg2;
      when "0001" => slv_ip2bus_data <= slv_reg3;
      when others => slv_ip2bus_data <= (others => '0');
    end case;

  end process SLAVE_REG_READ_PROC;
--
--  ------------------------------------------
--  -- Example code to drive IP to Bus signals
--  ------------------------------------------
  IP2Bus_Data  <= slv_ip2bus_data when slv_read_ack = '1' else
                  (others => '0');

  IP2Bus_WrAck <= slv_write_ack;
  IP2Bus_RdAck <= slv_read_ack;
  IP2Bus_Error <= '0';

end IMP;




ps2_keyboard.vhd

port
  (
    -- ADD USER PORTS BELOW THIS LINE ------------------
    --USER ports added here
	 ps2d, ps2c : in std_logic;
	 myinterrupt : out std_logic;
    -- ADD USER PORTS ABOVE THIS LINE ------------------

UCF and MPD files

The MPD file needs to be modified first. This will then allow us to add the io ports when mapping the device.

Microblaze Interrupt Handler

microblaze_register_handler(interrupt_handler_dispatcher, NULL);
                XIntc_EnableIntr(XPAR_INTC_0_BASEADDR, (XPAR_FIT_TIMER_0_INTERRUPT_MASK | XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK  | XPAR_PS2_KEYBOARD_0_MYINTERRUPT_MASK | XPAR_AXI_AC97_0_INTERRUPT_MASK ));
                XIntc_MasterEnable(XPAR_INTC_0_BASEADDR);
                microblaze_enable_interrupts();

Next

void interrupt_handler_dispatcher(void* ptr) {
        int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR);

  // Check the AC97. Just one method - no need for a separate handler
  if (intc_status & XPAR_AXI_AC97_0_INTERRUPT_MASK) {
          XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK);
          fillSound();

  }

        // Check the FIT interrupt first.
        if (intc_status & XPAR_FIT_TIMER_0_INTERRUPT_MASK){
                XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK);
                timer_interrupt_handler();
        }
        // Check the push buttons.
        if (intc_status & XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK){
                XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK);
                pb_interrupt_handler();
        }
  if (intc_status & XPAR_PS2_KEYBOARD_0_MYINTERRUPT_MASK) {
                XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PS2_KEYBOARD_0_MYINTERRUPT_MASK);
                ps2_interrupt_handler();
  }
}

PS2 Interrupt Handler

void ps2_interrupt_handler() {
  int buttonValue = XGpio_ReadReg(XPAR_PS2_KEYBOARD_0_BASEADDR, 0x0);
  xil_printf("rnValue0=%d",buttonValue);

  if (getGameInAction() == 0) {
                switch (buttonValue) {
                                // left button
                        case 28:
                                        setTankPositionGlobal(getTankPositionGlobal() - 5);
                                        drawTank(framePointer0);
                                        break;
                                case 27:
                                        if (!isHaveTankBullet()) {
                                                setHaveTankBullet(1);
                                                setHaveTankBulletSound(1);
                                                setTankBulletPositionX(getTankPositionGlobal() + 15);
                                                setTankBulletPositionY(TANK_Y_POSITION - 2*TANK_BULLET_HEIGHT);
                                                drawTankBullet(framePointer0);
                                        }
                                        break;
                                case 35:
                                        setTankPositionGlobal(getTankPositionGlobal() + 5);
                                        drawTank(framePointer0);
                                        break;
    }
  }
}

Yeoman’s Gruntfile.js with html5 hashbang

Description

Recently I worked on trying to make my angular application crawlable by google robots. In order to accomplish this I moved my application to html5. The problem however was all sites needed to be redirected from foo.com/newpage to foo.com/#!/newpage. This is required in order to load all the css and javascript for the page. No problem – Nginx is awesome and did this for me. I still had a problem. I want to use grunt serve to do local development work on the application. In order to accomplish this I found a great article talking about angular with html5mode when your application was constructed using yeoman. I ended up having to add mp3 and pdf file types to the mod_rewrite in order to get everything on my site to work. Either way – great article.

Async functions in AngularJS to behave synchronously

Description

Having a background in server side code entering the world of javascript’s asynchronous functional programming took a bit to wrap my head around and understand. Angular has some awesome libraries that let you make rest endpoint requests using $http module. There was a scenario I ran into recently where I needed to make a rest call to get some ip address information and then make another request based off of the information I received. Under normal synchronous programming this is not a problem, but there is no such guarantee with javascript. I needed to finally learn about callbacks and promises. Although they are similar I decided to go with a callback approach, which I will share here.

The basic premise to callbacks is you are passing functions as objects. The object is read and processed at a certain point. After understanding that functions are just objects in javascript the wheels started clicking in my brain and I was able to get my service to work properly. I made a service that handled the multiple http calls and then I just pass that service as a dependency injection of my controller. Below is just psuedo code on how I was able to accomplish this.




 
//Controller logic
//This makes the call to the service and when the service is done processing what it needs it then processing the function part of this.
$scope.getQuestion() = function() {
  MyService.getQuestion(index, function(question) {
    $scope.questionVariable = question;
  });
}

//Service Logic
this.getQuestion = function(id, cb) {
  this.getIPInfo(id, cb, this.retrieveQuestion);
};

this.getIPInfo(id, cb, retrieveQuestion) {
  $http.get("http://ipinfo.io").success(function (response){
    //On success then we call another function based on what we passed in;
    retrieveQuestion(id, cb);
  });
};

this.retrieveQuestion = function(id,cb) {
  // The cb is the callback from the original controller variable.
  $http.getsomething based off geolocation.success(function(data){
    // On successful call do some logic and set what we need in the question data
    cb(question);
    //This now has the var question completely set the way we need it to populate the original function call.
  });
};

Conclusion

Passing functions as objects is really a neat idea. Event driven asynchronous programming is taking me a while to wrap my head around, but it is really powerful and can accomplish the same end goal as synchronous programming — You just need to know how the beast of javascript behaves.

Review of CAD U37 USB recording microphone

Description

I have a couple of various websites that need to have lots of audio recordings in them. At first I tried using the microphone build into my computer screen. It’s great for video chatting, but when quality matters I needed a different solution. I spent time looking around on the internet for a couple of days to see what most people used for hobbyist or amateur recording microphones. After much delineation I chose to buy the CAD U37. Other models like the YETI have more features, which I probably will never use, and they come at a much higher price tag — $200+.

Pros

  • The microphone is under $50.
  • Has two control switches
    • Switch one is for removing loud noises or people who talk too loud
    • Switch two is to filter base or large frequency sounds – such as normal house ventilation.
  • Looks slick and works right out of the box
  • This is a directional microphone so it doesn’t pick up noises off to the side or in another room

Cons

The main con I have had was initially mounting this to the suspension boom. The boom did not come with a piece that could hold the microphone, however, the stand that the microphone came with could screw into the boom — You only need to unscrew the end from the boom and take the female extension out of the microphone mount and put that extension into the CAD U37 stand piece.

Conclusion

I highly recommend anyone who is starting to record – whether for music, your own podcast, or other hobbyist fun – should get this microphone. If you decide to buy it for just a few dollars more you should get the pop filter for it. The pop filter will help reduce spit sounds and odd air movements – like heavy breathing and etc. The pop filter also helps clarify the differences between a “B” and “P”. The CAD U37 microphone is the cheapest of the high quality microphones.

How to get google to crawl your angular application

Description

I first discovered there was a problem when I went to google’s webmaster tools -> fetch as google -> and submitted a page of one of my sites to be crawled. It had a hash “#” in the URL as that was the default routeProvider using the yeoman framework. To my surprise google would not crawl that page. After doing some research google stops indexing pages after a “#”, unless u do something kind of crazy to trick it.



Step 1: Enable HTML 5 routes in angular with bang prefix

Inside my app.js you need to enable html

.config(function ($routeProvider, $locationProvider) {
//
//
.otherwise({
        redirectTo: '/'
      });
      $locationProvider.hashPrefix('!');
      $locationProvider.html5Mode(true);
  });

This now takes all my URL’s from host.com/#/foo to host.com/foo. The biggest caveat to this approach is if I want to browse directly to host.com/foo my angular app throws a 404. This apparently is because the application didn’t load all the javascript it needed. I would have to go to the main page and click to each link I want to go. This simply won’t work – what production level site on the internet does this?

Step 2: NGinX magic

Come to find out if you go to host.com/#!/foo the page will load and then redirect you to host.com/foo and load everything for you. Well I don’t want people to see that happen in their browsers. Solution? Add a some rewrite logic to the nginx conf file to handle all these type of redirects for me.

  if ($args ~ "_escaped_fragment_=/?(.+)") {
    set $path $1;
    rewrite ^ /snapshots/$path;
  }




Conclusion

Now my site in production, which runs using angular’s routing, now has prettier URLs and can go directly to the page I need. I still need to figure out how to get my grunt serve to do the same magic as my nginx configuration. Every time livereload happens I get a 404. For more information on why I used a hashbang “#!” as my escaped_fragment – google has some good documentation they provided their developers as to why they make their search crawler act that way. When I made the change I went back to the Fetch as Google section and sent in my page with no hash marks in the middle. Google finally will be able to index all the pages of my angular app.

Using Curl In Bash For Endpoint Rest Testing

Description

Sometimes I am shelled into an environment or server that I cannot revers proxy through and I can’t run programs like Postman or Advanced Rest Client, which are great programs. I use the following aliases inside my .bashrc files in every server I set up because of how useful they are. This way we can test if a server has access to a particular endpoint or we can see the response of an endpoint called from the server.



# curl aliases
alias get='curl -X GET'
alias geti='curl -i -X GET'
alias post='curl -X POST'
alias posti='curl -i -X POST'
alias put='curl -X PUT'
alias puti='curl -i -X PUT'
alias delete='curl -X DELETE'
alias deletei='curl -i -X DELETE'

Single Line Program to Access a Docker Container

Description

I have several docker images I have pulled down and running in several containers on my server. As images update I destroy the old containers, remove the old images, and bring up the new images in a new container. Instead of running the following as root:

docker ps
CONTAINER ID        IMAGE                             COMMAND                CREATED             STATUS              PORTS                              NAMES
9ff50d7099b1        zaphinath/apirecisphere:latest    "/nodejs/bin/npm sta   46 hours ago        Up 46 hours         8080/tcp, 0.0.0.0:9800->9800/tcp   gloomy_albattani    
f2104cfaab88        zaphinath/apivietnamdocs:latest   "java -Djava.securit   2 days ago          Up 2 days           0.0.0.0:9700->8080/tcp             romantic_davinci 

You then have to find the container id and execute the following to enter the container if you ever need to debug something.

docker exec -it <docker_id> bash





There is a much easier way to accomplish this. I have a folder called bin in my home directory that contains lots of quick execution scripts and I have one for each of my docker containers. This allows me to access them when I need.

#!/bin/bash
docker exec -it `docker ps | grep recisphere | awk '{print $1}'` bash

Notes

This does not work as an alias because when the .bashrc loads the docker container id is loaded when the bashrc file loads. If the image updates you would have to reload the bashrc source to make an alias work. Having a small bash executables is a good alternative.

How to become a software developer

How to become a software developer

I am a software engineer and I often have people, whether they are in marketing, customer support, business development, or any other various positions in companies I have worked for, ask me “How to become a software developer?” So you want to learn to code. One of my favorite stories of all time comes from a legend of a young man who asked the Greek philosopher for his knowledge.

There’s an old legend about a proud young man who came to Socrates asking for knowledge. He walked up to the wise philosopher and said, “O great Socrates, I come to you for knowledge.” Socrates then led the young man through the streets, to the sea, and chest deep into water. Then he asked, “What do you want?” “Knowledge, O wise Socrates,” said the young man.

Socrates put his strong hands on the man’s shoulders and pushed him under. Thirty seconds later Socrates let him up. “What do you want?” he asked again. “Wisdom,” the young man sputtered, “O great and wise Socrates.”Socrates crunched him under again. Thirty seconds passed, thirty-five. Forty. Socrates let him up. The man was gasping. “What do you want, young man?”

Between heavy, heaving breaths the young man wheezed, “Knowledge, O wise and wonderful…” Socrates jammed him under again Forty seconds passed. Fifty. “What do you want?” “Air!” the young man screeched. “I need air!” “When you want knowledge as you have just wanted air, then you will have knowledge.”

I firmly believe that if anyone wants to learn they will not passively try to attain it. He or she will thirst for learning until that thirst can be quenched. If a person wants to become a programmer that is a great goal, but it does not happen over night. This is why software engineers are some of the highest paid professions in the U.S. Personally I think everyone should program, and if you desire to learn this article is just a short list of what I classify as “Critical” concepts to know as you learn. Think of this as a road map to point you in a direction. The rest is up to you.




Data Structures – Methods used to store information

There are so many programming languages in the world to chose from, and new ones are written every day. Understanding some basic data structures is crucial because all languages share this concept. We will start with what is called primitive types and expand from there. Think of primitive types like parts for building a house. You have cement, wood, shingles, drywall, and etc. Each part has a specific function to accomplish. You can then take the wood and arrange it in such a way to build walls. You can then take those walls and build rooms. Primitive types are similar. A primitive type can be organized to build a new data structure, which then can build a new one. Just like a carpenter or construction worker needs to understand what his building materials are he has to work with, a software engineer has a tool belt and one of his tools are data structures.

Let’s look at java as a building example. Java has eight primitive types.




  1. byte
  2. short
  3. int
  4. long
  5. float
  6. double
  7. char
  8. String
  9. boolean

A detailed explanation of these types can be found on Oracle’s Website.

Once you have a basic understanding of primitive types you can begin to arrange the primitive types into more complex data structures. The number of different data structures is comprehensive. I will only mention a few in this article. For a more detailed list any one of these books from Amazon will be full of great information.

Arrays

An array is a container object that holds a fixed number of values of a single type. The length of an array is established when the array is created. After creation, its length is fixed. An example could be an array of chars that would write the word “Hello” and it would look like this [H][e][l][l][o].

Lists

An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.

Trees

A tree data structure is a powerful tool for organizing data objects based on keys. It is equally useful for organizing multiple data objects in terms of hierarchical relationships (think of a “family tree”, where the children are grouped under their parents in the tree). The following is a visual of this. Trees are essential to more complex functionality. A great example is how google knows what you meant to type. IE: If I type the word “wrogn” and I meant to type “wrong” Google knows what you meant to type by using a structure known as a Trie Tree.
220px-Binary_tree.svg

Object Oriented Programming – OOP

The concept of object oriented programming is to organize your classes based off of real life objects. Example: Say I am trying to organize a list of people who live in an various cities I could use the following java class.

public class Person {
    private String name;
    private String title;
    private String address;
 
    /**
     * Constructor to create Person object
     */
    public Person() {
 
    }
 
    /**
     * Constructor with parameter
     *
     * @param name
     */
    public Person(String name) {
        this.name = name;
    }
 
    /**
     * Method to get the name of person
     *
     * @return name
     */
    public String getName() {
        return name;
    }
 
    /**
     * Method to set the name of person
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }
 
    /**
     * Method to get the title of person
     *
     * @return title
     */
    public String getTitle() {
        return title;
    }
 
    /**
     * Method to set the title of person
     *
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }
 
    /**
     * Method to get address of person
     *
     * @return address
     */
    public String getAddress() {
        return address;
    }
 
    /**
     * Method to set the address of person
     *
     * @param address
     */
    public void setAddress(String address) {
        this.address = address;
    }
 
    /**
     * Method to get name with title of person
     *
     * @return nameTitle
     */
    public String getNameWithTitle() {
        String nameTitle;
        if (title != null) {
            nameTitle = name + ", " + title;
        } else {
            nameTitle = name;
        }
        return nameTitle;
    }
 
    /**
     * Method used to print the information of person
     */
    @Override
    public String toString() {
        return "Info [" +
                "name='" + name + ''' +
                ", title='" + title + ''' +
                ", address='" + address + ''' +
                ']';
    }
}

Then in some other class we can call Person person = new Person() to initialize this object. A class should accomplish one main goal and do that really well. When a class starts to do more than one thing you should think of splitting that class into two objects. Once you start to understand the basics of objects and how to use them start looking into more advanced concepts of OOP such as Inheritance, Polymorphism, Abstract Classes, and Interfaces.

Big O Notation

Big O Notation is a way of calculating the impact of performance of different design ideas. A lot of languages can let you write really bad code. Understanding how your decisions affect speed is very important. Making your algorithms faster is really important when dealing with embedded systems, games, or mobile applications. Big O Notation




Use an IDE

When I was in college I was taking CS240 – Advanced Programming Concepts. About one third into the semester all students are required to take a programming test. No internet was allowed and we had to write a program assigned to us within three hours. I had ever used VIM, which is still a great tool, and I proceeded to program using vim. I barely made the cutoff time in three hours. I quickly learned that I needed to use a more powerful tool to help me with simple method calls and syntax errors as I was typing and not just when I was compiling my code.

From that point on I have used an IDE. IDE stands for Integrated Development Environment. IDE’s help users understand the methods that are called, help users understand syntax problems, can quickly create classes and refactor code, and above all have GREAT debugging tools available.

I have used various different IDE’s and two of my favorite free ones are either IntelliJ or Eclipse. If you don’t use an IDE – you should. They will bless your life.

Conclusion

How to become a software developer? In conclusion if you want to be a developer or engineer just keep learning as much as you can. Implement what you learn. Although there is no substitute for experience, getting your degree will also help fill in all the gaps that can arise from being self taught.

Using NginX Route to Plex Server Behind Firewall.

Description

If you have a router and want to limit access from the outside world to all the computers inside your home, then you will probably want to set up a server in a DMZ or forward specific ports to it. This open server can then route traffic to anything behind the firewall for you — acting as a proxy. I have used both Apache and Nginx, I like both, but In this article I will show an example using Nginx. Nginx has been proven to be able to handle more concurrent requests than apache and it is very lightweight.

Directions

There are lots of tutorials on the internet that show how to install and configure nginx. The general idea is when you install nginx there are to folders (usually in /etc/nginx/) called sites-available and sites-enabled. Good practice is to make a conf file inside the sites-available directory. Then execute the following command:

nginx -t

Once the configuration file is syntactically correct you can do a symbolic link to the same filename in sites-enabled. The following configuration shows one of my configuration files that routes request to plex.domainname.com to my plex server behind the firewall. If own a domain name then you need to edit the zone file and make an A record that points to the IP address of the router. When you then request plex..com the traffic will hit your router, go through the firewall to the server, and be proxied to another location via nginx.




NGinX Server Diagram

plex.conf
[enlighter language=”json”]
upstream plex-upstream {
# change plex-server.example.com:32400 to the hostname:port of your plex server.
# this can be “localhost:32400”, for instance, if Plex is running on the same server as nginx.
server :32400;
}

server {
listen 80;

# server names for this server.
# any requests that come in that match any these names will use the proxy.
server_name plex..com;

# this is where everything cool happens (you probably don’t need to change anything here):
location / {
# if a request to / comes in, 301 redirect to the main plex page.
# but only if it doesn’t contain the X-Plex-Device-Name header
# this fixes a bug where you get permission issues when accessing the web dashboard
if ($http_x_plex_device_name = ”) {
rewrite ^/$ http://$http_host/web/index.html;
}

# set some headers and proxy stuff.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;

# include Host header
proxy_set_header Host $http_host;

# proxy request to plex server
proxy_pass http://plex-upstream;
}
}
[/enlighter]