Archive for the ‘Everything Else’ Category

Frustration with Speed Coding Interviews

Wednesday, September 18th, 2019

Clojure.jpg

Yesterday I had an interesting phone screen with someone, and the seemingly common practice of asking a candidate to code on the phone - in a shared web-based environment again came up. I recognize that any employer can have any legal criteria for employment, and the "Coding Phonescreen" is a very common one. You get to see if the person can write code in a few minutes as opposed to inviting them for a day-long interview cycle that can cost considerably more. It's decent logic.

But it really doesn't tell the story, does it?

Speed Coding has about the same relationship to real development as a college classroom has to Jeopardy!... yeah, the material is the same, but the skills to be able to do well in one do not necessarily translate to the other. And the most critical skill in the speed forms is pattern recognition of the problem.

If you've seen this problem before, and written a simple solution to it, then you're in good shape. You know the flow, you know the pitfalls, and you can talk your way through it - like you're talking your way through directions to a local restaurant. No pressure, you're showing someone something you know, and it happens to take a few steps. No biggie.

But if you're at all unsure, then you're not going to get time to think about the solution before being expected to answer it. This is the problem with Speed Coding - if you know the answer, it's fine. But then it's not really seeing if you can think on your feet... if you don't know the answer, you're likely going to make one or two edge-case mistakes, and those will be clearly visible to the person that knows the solution.

The problem I ran into was a binary tree issue, and while I had been practicing my Speed Coding in Clojure, the nature of the binary tree really leaned towards a C++ solution, and that was not horrible, but it was a lot less friendly to edge-conditions.

I ended up writing something like this:

  struct Node { int value; Node *left; Node *right };
 
  bool stored(Node *me, op) {
    bool   retval = true;
    if (retval && (me->left != NULL) && (me->left op me->value)) {
      retval = stored(me->left, op);
    }
    if (retval && (me->right != NULL) && (me->value op me->right->value)) {
      retval = stored(me->right, op);
    }
    return retval;
  }

and the missed edge-case is that once you are one, or more, steps down in the tree, it's possible to have the relative position of the values be correct, but the absolute position to be false. There are two ways to solve this, in this code:

  1. Pass limits down with the call - this could be done with max and min arguments and then in the recursive calls, place the correct values there, and test them as well.
  2. Scan up the tree on each check - this could be a walk-up the tree and check to see that you aren't in violation of the location you have. This would take more time because of all the walking, but it'd work.

But what I'd wanted to do was to write it in Clojure, but the data structure didn't jump out at me. Until this morning. 🙂 This morning I spent the minute or two thinking about the data structure, and then formulated the following solution:

  ;; [val left right]
  ;;       10
  ;;    5      15
  ;;  1   7  12   20
  (def good [10 [5 [1] [7]] [15 [12] [20]]])
 
  ;;       10
  ;;    5      15
  ;;  1   17  12   20    -- the 17 is out of place
  (def bad [10 [5 [1] [17]] [15 [12] [20]]])
 
  (defn sorted?
    "Function to check a binary tree to see if it's sorted for proper
     searching."
    [[v lt rt] op]
    (let [ltv (first lt)
          rtv (first rt)]
      (and (or (nil? lt) (and (every? identity (map #(op % v) (flatten lt)))
                              (check lt op)))
           (or (nil? rt) (and (every? identity (map #(op v %) (flatten rt)))
                              (check rt op))))))

What I really like about this solution is that it checks the entire subtree with the operation. This means that the effort to do one, is really checking all of them. This is what I wanted to write, and it works perfectly.

But I didn't force the issue, and pull back and take the time to think. My mistake. I won't make it again.

UPDATE: a friend and I were talking about this same problem, and he came up with a solution that was very clever - the structure can be validated by simply assuming that the structure is a sorted binary tree, and then calculating the min and max values of the tree.

The catch being that if you get to a node where the current value isn't within the min and max, then you have to fail, and return nil. It's really quite amazingly simple in that it's very fast, very easy to understand and adds the additional benefit of returning the extremum of the tree.

  (defn bst-rx*
    "returns extent [min max] of valid bst or nil if invalid"
    [t]
    (cond
      (nil? t) nil
      (vector? t) (let [[v l r] t
                        lx (if l (bst-rx* l) [v v])
                        rx (if r (bst-rx* r) [v v])]
                    (when (and lx rx (<= (lx 1) v (rx 0)))
                      [(lx 0) (rx 1)]))
      :else [t t]))
 
  (defn bst-rx?
    [t]
    (boolean (bst-rx* t)))

Thrown for a Bit of a Loop

Tuesday, September 17th, 2019

hostmonster.jpg

Yesterday morning, I thought to check my blog and see something, but to my complete surprise, it was down. Like very down, and I had no idea what was happening. I've been using WordPress and HostMonster for more than a decade, and I've never had anything even remotely like this. I didn't know where to start - so I went to their admin site, thinking I'd been hacked somehow...

First, it was clear that they had done a ton of upgrades to the host and its support platform. Massive changes. So the first thing was to get logged in. This was a little odd because it wasn't working on Safari, and it had been in the past - so I switched to Chrome, and finally got logged in. Step 1 - accomplished!

Then I looked at the installed users on each of the three WordPress sites I have, and in each case, there was a user that I couldn't explain. It certainly appeared to me that these were bad actors, and I had no idea how they got there. I stay up to date, don't allow logins, don't allow replies... it's a Journal more than anything else. But still... I could not deny these accounts. So I asked for help.

php.jpg

It took a long while to figure this out, but in the end, the logs for the site indicated that there was a PHP problem in one of my plugins, and one of my themes. Why this happened yesterday wasn't at all clear, but it became clear as I dug further.

HostMonster had dropped support for PHP 5.x, and the only versions available to me were 7.0, 7.1, 7.2, and 7.3, with the latter being the default. Now it seemed to be clear what had happened... nothing had changed, but in all the upgrades for the infrastructure on the hosts, they had switched to a different config for PHP, and the plugin and theme were doing something that they shouldn't. OK... now to the code.

The first one I tackled was the plugin, as the error in the logs was pretty clear. I did a quick search for =& and sure enough, it was a PHP 5-ism, and that was easy to fix. That solved the plugin problem, and it loaded and ran fine. The theme had a different problem with a deprecated function that wasn't really even needed in the theme, but I found a replacement, and used that, and the theme was fine.

All told, this took more than 5 hours... it was not quick, and I just ahead of the part where I found out that the timezone plugin I was using wasn't needed in WordPress 5, and so I didn't put that back into play, Also, when I got the site up, it was possible to see the errors on activation of the plugin (but not the theme), which made continued debugging a lot easier.

In the end, it was all cleaned up, and now it's set for PHP 7. I'm glad that there wasn't a bigger issue, but I really have to be careful of these things because there is almost no support for the plugin and theme - and I really like to have both of them working for me for this blog. 🙂

Quick Update on the Apple Card

Wednesday, August 21st, 2019

AppleCard

Just a little update on the Apple Card, and how it's been to use, now that I've had the physical card in-hand for a week now. In short - the card is physically very nice - I like the heft and the fact that it's got no identifying marks on it but my name, and that it doesn't get deformed in my wallet. But what's really setting it apart is the Wallet app on my iPhone.

Apple Card

I had been using the Capital One Quicksilver card, and still carry it now - but all my recurring expenses, and online services, have moved over to the Apple Card. The Capital One app had notifications, and that's become pretty much table stakes for credit cards these days - my Bank has it, Capital One, and Apple. But it's the frictionless nature of the Apple experience that is really what this card means to me: Service.

A card is a card - I'm one of the very lucky ones that doesn't have to worry about interest rates - I pay it off every month - without fail. So the limit matters, but only a little, and so it's really the services, the help in tracking purchases, verifying that they are correct, and in a timely manner - that I really care about. And in that regard, the Apple Wallet app is just going to be so much better at it than the Capital One developers - because they only have to build for one platform (theirs), and they have the advantage of handling security in any way they want.

It's made it much easier to see what's happening, keeping track of the charges/purchases, and the easy way to see what gets the different cash-back percentages has been baked-into the UI on the list of charges. It's really quite good. But that's the point - Apple is going to be focused on the Service and experience of the user, and not on the financials that another issuer will be.

I have to say, I'm really enjoying it. 🙂

UPDATE: I followed the advice on Daring Fireball to opt-out of the arbitration clause on the Apple Card, and it could not have been easier. Everything was done in the Messages app... just go into the Wallet, hit the three-dots, and select Message, and text that you want to exercise your right to reject the arbitration clause.

They will transfer the chat conversation to a Goldman employee, and then they will see it, and mark you down as having opted-out of the arbitration clause, and that's it. No mess. No fuss. This is the way technology should empower us.

Signed Up for the Apple Card

Monday, August 12th, 2019

AppleCard

I got an invitation to sign up for the Apple Card last week, and went through the sign-up process in the Wallet app, and found out that it was going to be pretty much as good as my Capital One Quicksilver card - with the added security features of not having my purchasing history sold. It's something that I was really looking forward to when it was announced at WWDC.

Today, the physical card arrived, and I'll activate it when I get home, but so far, the card is working exactly as promised. I do a lot of Apple Pay, and that's all working just fine. I had to Add a Card on my Mac and iPad - but the Apple Card was there, and it was easy to add, and other than that, it's just so easy. Nothing fancy about the purchase classifications, but it's nice... and the details come up a little faster than the old Capital One app - but that wasn't all that bad.

It'll be interesting to see the card, and see how the payment feature works. I have to admit, it's a little different to have my iPhone link to my Bank, as opposed to using the online bill-pay system from my Bank - but either way - it works, and the effect is the same.

Life keeps adding little smiles... 🙂

Very Funny Tweet about Scaling

Tuesday, July 9th, 2019

Amazon EC2 Hosting

Yesterday I saw this very enjoyable tweet and it made me smile - quite a lot... because I do interviews often, and they are almost always about Architecture and Design, and scaling is one of the key use-cases to explore. It really helps see how the candidate approaches the problem:

Used to pay $5/mo on a small instance for my personal site. Then I discovered Kubernetes and realized my site didn't scale! No canary deployments! So I upgraded and pay $200/mo now. Took weeks to configure. Millions of people can now read my resume. Damn, it's never looked better
-- @malaroto

When faced with a scaling problem, AWS has been amazingly good - and amazingly bad for junior developers on the path of learning their craft. On the up-side, it's wonderfully full-featured, stable, available, on-demand in every way, and global. On the downside, it doesn't require any effort to use - so the first answer most jump to, is to build something that doesn't need to be built with unnecessary complexity that will work, but slows down the ability for someone else to understand the solution, and it's basically just wasting money.

"Not my dime" - is accurate, but not really the point. The point is to understand the problem, and then fix the problem, but if everything is able to be solved with millions of dollars of computing infrastructure, there seems to be no motivation to solve it with an hour of understanding and code refactoring.

So I giggle... they will have their day - a massive supercomputer in a grain of sand - ubiquitous and omnipresent... and then there will be no need to understand the why of issues... and that will be too bad. There will always be a need for craftsmanship.

Colors Can Be a Dangerous Thing

Monday, July 8th, 2019

Google Docs

This morning I was just checking over a few Google Docs where I'd made some comments for the author, and wanted to see if there was still a reason to keep the doc(s) open to make it easy to respond to the notes, or resolve them for the author. And I noticed that the author had chosen to use an odd color for the word Draft in the header - Goldenrod. Now I'm not a style snob... but that struck me as an odd color for something that you might want to draw attention to. I mean, the text is black on white, and then there's the obvious red for alarm, and green for good... but what about the non-obvious Draft?

And then it got me thinking about the other really unusual uses of color I've seen at The Shop on documents -- and I"m not talking about spreadsheets - I think those are universally accepted as examples of hideous color combinations... No, these are documents that have had background colors... foreground colors... just amazing combinations, that seem to have no sense as to why they are colored this way.

And it isn't something that I have to correct - it's just something that makes me giggle, and I need to put a face with the color choices, and it's usually someone that is not what I'd call a Creative Professional. It's understandable - they want things to stick out - but with so many things that need to stick out, they have to use colors to classify them. It's just like the line from The Incredibles:

Then when everyone is super, no one will be.
- Syndrome

But that doesn't stop some folks from making the most creative color pairings I think I've seen. It's just something I find funny about people... we're all different, and we all bring our own background to everything we do. 🙂

The Year is Half Over

Monday, July 1st, 2019

Path

Well... this morning the year is half over, and I find it hard to believe. It's nice to see that Summer has arrived... the sun is out, the temps are in the 90s... the year has really left Spring behind. It's going to be a while before the leaves fall... there's a lot of yard work to do this summer, and it's going to be a nice summer.

Yet today really has crept up on me. It was quite something to look back and think how much has really happened this year. A daughter graduated college... I made it to a year at The Shop... things are settling down. Life moves on.

It's important to try to make a note of these passages of time.

Updating my WordPress CodeHighlighterPlus to GeSHi 1.0.9.0

Thursday, March 28th, 2019

wordpress.gif

This morning I decided to see if I couldn't fix the Swift highlighting on this blog by updating to the latest GeSHi 1.0.9.0 - which is now using PHP 7, and as it turns out, so is HostMonster, so I'm in luck! 🙂 At the same time, I really wanted to document all the components and links so that this post makes it a lot easier to update things later.

As a point of reference, the CodeHighlighterPlus project is based off the CodeHighlighter WordPress plugin, and it's not bad - it's just not been updated in many years, and there are a lot of added languages in that time. Still... I tip my hat to the original authors, as I couldn't have done it without them.

The steps to do this required a little digging, but that wasn't bad - in that I had a few posts about this process already, and so let's just repeat them here to make sure it's all clear for the next time. I started by making sure that my local CodeHighlighterPlus plugin was up-to-date with the GitHub repo. All good, so let's get the latest code from GeSHi, and just overlay it on the local repo. Replace where necessary, and then we're up to date with GeSHi... but it's not really cleaned up the way I like it.

The next thing was to update the geshi.php file for a few changes. The first thing I wanted to tackle with CodeHighlighterPlus was the line numbers. There was far too much space between the lines in a code sample with line numbers. This is corrected simply in the style for the lines:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'font-weight: bold; vertical-align:top;';

to:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'margin: 0; font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'margin: 0; font-weight: bold; vertical-align:top;';

The last change is for the blank lines that start, and end, the code section when you use line numbers. It's just plain annoying. Change:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. $parsed_code = $this->header();

to:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. // remove a blank first and last line
  5. if ('' == trim($code[count($code) - 1])) {
  6. unset($code[count($code) - 1]);
  7. $code = array_values($code);
  8. }
  9. if ('' == trim($code[0])) {
  10. unset($code[0]);
  11. $code = array_values($code);
  12. }
  13. $parsed_code = $this->header();

and we are good to go with the changes to the code. Check everything in, push it up to GitHub and we're ready to deploy it.

At this point, I just need to deploy this to each of the WordPress sites on my server - and that's as simple as:

  $ cd public_html/blog/wp-content/plugins/CodeHighlighterPlus
  $ git pull

where blog is the directory in the WordPress content for the specific blog I'm working with. I simply use GitHub as the mechanism of deployment - with a pull system to make sure it doesn't mess too much stuff up.

In this release of GeSHi, we now have support for the following languages:

4cs            e              magiksf        qml
6502acme       ecmascript     make           racket
6502kickass    eiffel         mapbasic       rails
6502tasm       email          mathematica    rbs
68000devpac    epc            matlab         rebol
abap           erlang         mercury        reg
actionscript   euphoria       metapost       rexx
actionscript3  ezt            mirc           robots
ada            f1             mk-61          rpmspec
aimms          falcon         mmix           rsplus
algol68        fo             modula2        ruby
apache         fortran        modula3        rust
applescript    freebasic      mpasm          sas
apt_sources    freeswitch     mxml           sass
arm            fsharp         mysql          scala
asm            gambas         nagios         scheme
asp            gdb            netrexx        scilab
asymptote      genero         newlisp        scl
autoconf       genie          nginx          sdlbasic
autohotkey     gettext        nimrod         smalltalk
autoit         glsl           nsis           smarty
avisynth       gml            oberon2        spark
awk            gnuplot        objc           sparql
bascomavr      go             objeck         sql
bash           groovy         ocaml-brief    standardml
basic4gl       gwbasic        ocaml          stonescript
batch          haskell        octave         swift
bf             haxe           oobas          systemverilog
biblatex       hicest         oorexx         tcl
bibtex         hq9plus        oracle11       tclegg
blitzbasic     html4strict    oracle8        teraterm
bnf            html5          oxygene        texgraph
boo            icon           oz             text
c              idl            parasail       thinbasic
c_loadrunner   ini            parigp         tsql
c_mac          inno           pascal         twig
c_winapi       intercal       pcre           typoscript
caddcl         io             per            unicon
cadlisp        ispfpanel      perl           upc
ceylon         j              perl6          urbi
cfdg           java           pf             uscript
cfm            java5          phix           vala
chaiscript     javascript     php-brief      vb
chapel         jcl            php            vbnet
cil            jquery         pic16          vbscript
clojure        julia          pike           vedit
cmake          julia.bak      pixelbender    verilog
cobol          kixtart        pli            vhdl
coffeescript   klonec         plsql          vim
cpp-qt         klonecpp       postgresql     visualfoxpro
cpp-winapi     kotlin         postscript     visualprolog
cpp            latex          povray         whitespace
csharp         lb             powerbuilder   whois
css            ldif           powershell     winbatch
cuesheet       lisp           proftpd        xbasic
d              llvm           progress       xml
dart           locobasic      prolog         xojo
dcl            logtalk        properties     xorg_conf
dcpu16         lolcode        providex       xpp
dcs            lotusformulas  purebasic      xyscript
delphi         lotusscript    pycon          yaml
diff           lscript        pys60          z80
div            lsl2           python         zxbasic
dos            lua            q
dot            m68k           qbasic

And with the addition of Swift, I have highlighting on all the code snippets I've been adding. Very nice!

The Dreadful State of IM Clients

Thursday, March 28th, 2019

Adium.jpg

Yesterday morning I noticed that ICQ wasn't connecting within Adium - it was failing to connect with the error:

Error: Unable to connect to BOS server: Connection refused

and nothing I could find was changing that error. Now, to be fair, I can't ever remember using ICQ for chatting with anyone, but when I got Adium all those years ago, I made sure to get accounts on all the supported platforms so that I could be available to anyone wanting to chat.

Sadly, one by one, they have fallen off... or shut down... or locked down the services to only allow proprietary client access. I guess I get it, I'm just seeing the monitization of all these chat clients - HipChat, then Slack and Google Hangouts... and those are the ones that are still alive. Hotmail went to Microsoft, and then they shut it down. AOL - gone. Yahoo! - gone.

I now have Adium that hasn't really been updated in about a year, and it's got one client: Gtalk. And we know that this is getting shut down soon by Google to force us all to use their Hangouts client. I guess it's just the pendulum swinging back to the "Give me my money!" - but for folks like Microsoft and Google - do they really need the money they'd get off me using Skype or Hangouts?

The truth is that I won't use either - except for work, and there I have to so it's a captive audience. But what they've really done is pushed me to use my phone. I can text all these folks, and make group texts, and I can use any phone I want.

It's just so very sad.

UPDATE: yup... I did a little searching on the net to see what's up, and it turns out the owners of ICQ have decided that 28-Dec-2018 was the cut-off date for the old protocol that was supported in libpurple - which is used by Adium. Just another case of trying to monetize the IM space. In this case, I'm OK with letting this one go. Not worth the tracking risks for ICQ.

Apple News+ is Pretty Nice

Tuesday, March 26th, 2019

Apple Computers

This morning I signed up for Apple News+ - and I have to say, it's pretty nice. Sure, it's having some growing pains this morning - the News app in iOS 12.2 is crashing a bit when it can't talk to the servers at Apple HQ, but that will get worked out. For the little time it was stable this morning, I was really impressed with the offerings - some things I have paid for in the past, but just haven't kept up with, and others I've always wanted to have available to read:

  • Scientific American
  • Time
  • Runner's World
  • The Wall Street Journal
  • Bloomberg Businessweek
  • The New Yorker
  • The Atlantic
  • Flying

it's a list that keeps going, and it's really impressive. Sure, it's more than $30/yr - but that's for one magazine, and I can carry these all with me in my pocket on my phone. It's really just amazing.

Now, I've been reading a lot more on the News app because I just can't stand Facebook any more, and this is a lot better place to get news - it's a known source, and that's something I find I don't like about all the stuff you find on Facebook - you just can't trust it.

I'm not sure about the other services they introduced yesterday - except the Apple Card. That's something I'll get because of the Daily Cash Back that I can use because I put so much of my life on my Quicksilver card with 1.5% cash back. This is just a better deal.

Can't wait for the Summer when they get that going...