In August 2014, I quit TV for a month. You can read the reasons why in my previous post, I Am Quitting TV for 30 days! This post chronicles the unexpected challenges I encountered, the changes I made, and the conclusions I reached. Read More
The New Poetry
Yoga is the new poetry.
Meditation is the new poetry.
Mindfulness. Beauty and rawness of soul and spirit.
TV has chased away our poetry, and we seek to regain it through yoga, meditation, and mindfulness.
Somehow poetry itself can no longer compete.
I am Quitting TV for 30 Days!
Today begins my 30 days without television. It is my sincere hope that after 30 days, I will have broken the hold of this incredibly powerful habit that unconsciously drives me to turn on the TV, and spend hours sitting passively when there are so many other things I would love to do with that time. Read More
How to Pick the Best Calorie Counter App
Calorie counting apps help you track your daily intake and calorie expenditure. You enter what you eat a few times a day, and an app keeps track of how many calories you’ve consumed and how many calories you have left for the day. Read More
Debugging Access-Control-Allow-Origin issues in Apache
Here’s how I was able to solve & debug a problem relating to a security issue that prevented iPad and Android devices from loading some of the files on my site, due to the fact that they were served by a different port. Client side (browser) tools did not provide the level of insight I needed to debug the server issue.
The problem:
I was running Django server on a port (8000) with Apache serving static files from port 80. On iPad and Android devices, my JWPlayer 6 video player was giving users an error that my custom skin file could not be found. The skin file was simply an xml file being served by Apache on the same machine, and it worked just fine on laptops, desktops, Mac and PC, but not mobile, and not tablets.
I found the underlying client problem first with Mac iOS Simulator and Safari Developer tools (and later by simply spoofing the Android user agent from my Chrome browser and checking Console errors). The error was:
XMLHttpRequest cannot load http://localhost.myhost.com/static/inc/jwsk/glow_gb.xml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost.myhost.com:8000' is therefore not allowed access.
I found a number of reports on the issue, including this Stack Overflow post. To correct my problem, I needed to setup CORS (Cross-Origin Resource Sharing) via some Apache directives.
I verified that the loosest setting in Apache did indeed fix the problem, so I was on the right track:
<FilesMatch ".xml$"> Header set Access-Control-Allow-Origin * </FilesMatch>
However I wanted stricter security in place, to not allow any old hostname to match. Based on some misleading statements in the StackOverflow thread, I believed I could use multiple lines for this Response Header, using environment variables to generate different combinations of host & port that I wanted to allow. I tried dozens of combinations unsuccessfully and struggled to figure out how to debug the apache behavior. Finally I found
this post (http://archive.ianwinter.co.uk/2010/11/18/log-response-headers-in-apache/) which got me headed in the right direction.
Debugging the issue
I added the following lines to my apache conf file, to emit to my logs both the environment variables I was setting & request/response headers relevant to the issue:
#capture server & host from request origin SetEnvIf Origin "^(.*.?myhost.com)(:[0-9]+)?$" ORIGIN_0=$0 ORIGIN_1=$1 ORIGIN_2=$2 # add variations of incoming host/port to the response headers <FilesMatch ".xml$"> Header set Access-Control-Allow-Origin "%{ORIGIN_0}e" env=ORIGIN_0 Header set Access-Control-Allow-Origin "%{ORIGIN_1}e" env=ORIGIN_1 </FilesMatch> #emit request "Origin" header, response "Access-Control-Allow-Origin” header, and my 3 environmental variables to each line of the log LogFormat "%h %l %u %t "%r" %>s %b ORIG="%{Origin}i" ALLOW="%{Access-Control-Allow-Origin}o" O0="%{ORIGIN_0}e" O1="%{ORIGIN_1}e" O2="%{ORIGIN_2}e"” common2 #use my custom log format CustomLog /var/log/django/prototype_access.log common2
After restarting apache, my apache logs now showed output like this when I reloaded an affected page:
127.0.0.1 - - [15/Mar/2014:13:41:26 -0700] "GET /static/inc/i/logo2.png HTTP/1.1" 304 - ORIG="-" ALLOW="-" O0="-" O1="-" O2="-" 127.0.0.1 - - [15/Mar/2014:13:41:26 -0700] "GET /static/inc/i/unlimited.png HTTP/1.1" 304 - ORIG="-" ALLOW="-" O0="-" O1="-" O2="-" 127.0.0.1 - - [15/Mar/2014:13:41:26 -0700] "GET /static/inc/jwsk/glow_gb.xml HTTP/1.1" 304 - ORIG="http://localhost.myhost.com:8000" ALLOW="http://localhost.myhost.com:8000" O0="http://localhost.myhost.com:8000" O1="http://localhost.myhost.com" O2=":8000"
Eureka.
The Solution
I could verify via apache logs that my environmental variables were working as expected. My problem was that only one of my Access-Control-Allow-Origin headers was taking effect, and not the right one. I needed to Allow origins without the Django port.
Once I removed the extra lines, I was left with this configuration, which solved my problem by enabling the Apache host (without the django port) in a single response header directive.
SetEnvIf Origin "^(.*.?myhost.com)(:[0-9]+)?$" ORIGIN_1=$1 <FilesMatch ".xml$"> Header set Access-Control-Allow-Origin "%{ORIGIN_1}e" env=ORIGIN_1 </FilesMatch>
My final apache logs looked like this:
127.0.0.1 - - [15/Mar/2014:13:41:26 -0700] "GET /static/inc/jwsk/glow_gb.xml HTTP/1.1" 304 - ORIG="http://localhost.myhost.com:8000" ALLOW="http://localhost.myhost.com" O0="http://localhost.myhost.com:8000" O1="http://localhost.myhost.com" O2=":8000"
Robot Vacuums (Neato)
June 2014 Update:
I have grown to adore my Neato.
Visitors comment on how clean my floor is. I simply hand-vacuum the edges of the room once a month, to get the areas the Neato can’t. I walk barefoot around the house all day, and don’t have to wipe my feet to get in bed. It runs 3 times a week to keep things spic and span, and only gets stuck once every few weeks. I’ve gotten into the habit of keeping my phone charging cords off the floor, and for a few bucks, I purchased a 10-ft cord organizer for all the cables running behind the couch. The Neato avoids it. I even carried my Neato up to the attic and let it suck up the dust and guck that only an attic can collect. That was a perfect job for a robot!
Dec 2013:
This Christmas, I finally got something I’ve wanted for years, a robotic vacuum. My dog leaves a literal trail of hair in her wake akin to PigPen’s dustcloud, so this bot has its work cut out for it. On a friend’s recommendation (about the quality of the cleaning algorithm), I got the Neato (XV-14) instead of the more well-known Roomba.
Day 1. Gratification and disappointment
Wow, it’s a lot louder than I was expecting. The dog doesn’t love it, but she tolerates it. It moves SO slowly (~15 minutes for a 10×10 room with almost no obstacles, about an hour for 4 small rooms).
It doesn’t clean the edges of the room, nor behind/around things, which is where a lot of the dog hair tends to collect. Even so, it filled its dirtbin twice on day 1, so that was very gratifying. Quite amusing to see it climb my digital scale, push the dog bowl and even a chair. Ran out of juice once requiring a recharge, and made a bit of a scrunched up mess of my lightweight kitchen rugs, though it managed to not get stuck on them.
Day 2. Learning boundaries and eating cords
Today I set up the auto-schedule feature so it would run mid-day on a different floor of the house (I work from home), to be away from the noise.
- Within a few minutes of auto-starting, I heard the Neato’s oddly pleasant bleet for help. It had sucked up the end of my new iPhone charger and stopped. Stripped a bit of plastic from the wire but didn’t kill the cord thankfully. I cleared the obstacle and vacuuming resumed.
- A few minutes later, another bleet as the vacuum had managed to get stuck on a different cord. Never realized how many cords I had laying around. Cleared that too.
- A few minutes later, it got stuck under the couch next to a bunch of cables (but not having eaten them), complaining its vision was blocked. Though I moved it to an open space, the error code would not reset on its own until I put it back on its dock. That cleared the error state right away.
- At some point it ran out of power 6 inches away from its dock and stopped there. I manually redocked it.
Day3. Skipped
Didn’t schedule it to run. Kinda missed it.
Day4. Stops and starts
Today I was smart and moved everything out of the way ahead of time, cables, obstacles, etc. The vacuum started on its own schedule, which was great.
- I heard it stop after 10 minutes or so and found that it had redocked and claimed it was finished. My still visibly dirty floor and the short run period were evidence it had skipped most of the floor, so I manually restarted it.
- A few minutes later, I heard it shut off again. This time it ran out of juice but made it back to its dock for recharging. They say it takes a few charges to hold its full charge. Later it restarted on its own.
- Stopped shortly thereafter again. The display reported that the brush was stuck. Apparently my long hair had wrapped around it and knotted. This required a quick (and easy to find) Youtube lesson on how to remove and take apart the brush, which only took a few minutes and wasn’t hard. Given my hair, I’m sure I’ll need to do this on a regular basis. The error code wouldn’t clear on its own, so I redocked it and that cleared it.
Did a decent job cleaning today and it was satisfying to empty the half-full waste collector.
The deceased live on LinkedIn
In the relatively young landscape of social media, one awkward area has to do with the accounts of the deceased on LinkedIn.
I now have 2 friends on LinkedIn who have died unexpectedly young. Both are still active on LinkedIn, and show up as still working at their last job. I dread the day that I am prompted to Congratulate one of them on their n-year anniversary at their ‘current’ employer. As time goes on, the number of dead on social networks will inevitably grow. And grow.
There’s a part of me that rejoices in seeing my friends’ names again, having a way to visit their pages and feel the idle connection come alive. But on the heels of that feeling comes the inevitable knife-in-the-gut, the remembrance of the loss: a cruel, insensitive reminder.
LinkedIn provides a way for members to report accounts of the deceased to initiate account shutdown. Generally, I would hope that a family member would get to make this decision, and not a colleague.
These accounts are living epitaphs. Miss you guys.
açai
Açai do Brasil
Beneficios del açai
que es el acai
Acai Berry Best to Use Beneficios del açai – Açai do Brasil
acaidobrasil
www.acaidobrasil.top
Getting Things Done…
You know what happens when you do things…. things get done.
AWS Command Line Interface (aws cli) Tips
Today I started playing with the new Amazon Web Services command line interface tools to issue aws commands from my console and scripts.
Installation was straightforward, but I realized right away I needed to set the target region for my commands, so I decided to use the custom config file approach, setting an env variable AWS_CONFIG_FILE to point to my config file path.
The aws cli tools are not very well documented yet, and there are multiple obsolete versions of the docs floating around as well, so here are a few quick corrections.
Regarding your AWS config file:
1. You must explicitly prefix named config sections with “profile”, e.g. [profile oregon], not [oregon].
If you do not, an otherwise valid config file does not work, yielding this error.
A client error (InvalidLocationConstraint) occurred: The specified location-constraint is not valid
Here’s a valid config file:
[profile oregon] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY #oregon region = us-west-2 [profile norcal] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY #n. california region = us-west-1
2. Inline comments are not supported in the config file, only full-line comments.
If you do use an inline comment in your config (as one of their examples does), you may see the error I saw:
A client error (InvalidLocationConstraint) occurred: The specified location-constraint is not valid
So this inline region comment is invalid:
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region = us-west-2 #oregon
3. There is no fallback to env variables if you skip variables in the config.
Even though I set AWS_ACCESS_KEY and AWS_SECRET_KEY into my environment, I get error
Unable to locate credentials
So here’s another bad file.
[default] region = us-west-2 #missing aws_access_key_id #missing aws_secret_access_key
Preparing for Technical Interviews
For the last 2 years, I’ve surveyed my colleagues in engineering positions around the country (mostly the San Francisco bay area), asking their advice on DOs and DONTs for technical interviewing. I’ve combined their advice – representing companies that include Google, Twitter, Rackspace, Mozilla, LongTail Video, Wharton, Cloudera, and Crompco, among others – with my own experience as a hiring engineering manager at Ask.com, and summarized that advice below. While not a ton has changed in the hiring practices since last year, there has been an increase in Big Data and cloud-related jobs, hence an increased emphasis on knowledge of distributed systems for those positions.
Though some of the advice here is specific to engineering roles, most of it is applicable to any position, technical or not. Here is a summary of our collective 2013 advice for job seekers.
What Technical Interviewers are Looking For
Preparing for an Interview
If You Struggle During an Interview
If You Don’t Get the Job
What Technical Interviewers are Looking For
Demonstrable coding (for engineering positions)
- Write code or whiteboard; don’t just answer verbally
- …no proof => no offer
Problem-solving and Tenacity
- Talk aloud so interviewer sees your thought process
- Admit when you don’t know
- Ask clarifying questions
- Start with simplest solution then iterate
- Consider edge cases (exceptions, test cases)
- Get it working first before optimizing
Honesty
- Don’t misrepresent yourself
- Be honest about the past details of your resume
- Be honest about your strengths, weaknesses
- Use both “I” and “We”
- “We” indicates team player, but too much “we” indicates you were not a leader or may be weak
- Be diplomatic! no badmouthing people, companies
Passion / Curiosity
- …for the job
- …for the company/industry/technologies they use
- …for outside interest/hobby – can help cover gaps in resume
Communication Skills
- Speak clearly
- Show you can comfortably communicate complex thoughts and ideas
Composure & Confidence
- Stay positive, can-do, confident (fake it if needed)
- Relax, breathe if you’re nervous, slow down if you’re speaking fast
- Remember that interviewers want you to succeed
- Think of a person that inspires you to be confident; put a photo of them on your phone
Connections & Cultural Fit
- Reach out to any company contacts you have, ask them about fit
- Get employee referral – gives you advantage getting an interview
- Use your extended networks to get a referral or informational interview
Above & Beyond
- Contribute to open source project
- Get a GitHub account and share your code with employer
- Show domain expertise on StackExchange/Overflow
- Demo something relevant during interview
- Teach the interviewer something
Preparing for an Interview
General Tips
- Do homework on the company, its technologies, and its industry
- Be prepared to offer opinions, suggestions for their products or UIs
- Interview elsewhere to gain experience before you interview for your dream job
- Practice writing code by hand, on whiteboard or paper
- Ask HR/hiring manager what skills are important *for the interview*, what technologies company uses
- Bring questions to the interview, especially technical ones
- Review your resume in detail then fill out a Behavior Preparation Grid (Excel spreadsheet); Memorize your answers
- * Grid by Gayle Laakmann McDowell, CEO of interview prep resource CareerCup.com
- Practice answering questions aloud (roleplaying or solo)
- …the more you practice, the faster & more naturally responses will come to you during the interview
(On-site) Interview Day Preparation
- Appearance
- …business casual for Bay Area tech, or one step up from what the employees typically wear
- …suit for non-technical companies, including financial institutions
- Wear something comfortable, layers if possible (could be freezing, could be hot & stuffy – don’t want pit stains!)
- Wear deodorant
- Prepare for a long, mentally exhausting day
- Stay hydrated, meter your caffeine
Technical Preparation Subjects
- In general, study up on:
- basic algorithms (incl tree traversal)
- data structures
- networking
- As relevant to the position, review:
- concurrency primitives
- garbage collection
- how interpreters work
- system calls
- kernel internals
- For big data or cloud role, or company with problems of scale, study:
- Hadoop, Map Reduce, HDFS, Hadoop ecosystem
- distributed systems
- how data structures scale in distributed applications
- distributed algorithms
If You Struggle During an Interview
- …not a deal breaker (up to a point), almost no one is perfect
- Ask questions, work with interviewer to show collaborative skills, show interest & curiosity
- Ask for hints and use them, don’t ignore
- Show interesting problem solving (even if wrong), not just brute force
- Ask them to explain solutions you missed, it’s a learning opportunity
- Stay positive, confident
If You Don’t Get the Job
- Don’t beat yourself up, identify opportunities for improvement
- View it as valuable interviewing practice
- Understand that interviewing and hiring can be somewhat arbitrary
- Interviewers make mistakes, have bad days, may be poor or inexperienced at interviewing
- Company may be holding out for a candidate/skillset that they won’t find, and you interview before they adjust their expectations
- If you love the company, inquire about other teams or the policies for reapplying
- Not uncommon for companies to hire people they previously declined
A few more resources
Great book to help engineers prep: Cracking the Coding Interview: 150 Programming Questions and Solutions by Gayle Laakmann McDowell, CEO of online interview prep resource CareerCup.com
First 70 pages are great for all job seekers, rest of the book is practice questions for engineers (algorithms, data structures, java, c/c++, databases, threads/locks, testing).
Check out the full set of advice gathered from my surveys on this Google Doc spreadsheet.