the corner office : tech blog

a tech blog, by Colin Pretorius

New PC

It's taken 11 loooong years since we moved to the UK, but I finally have a desktop PC again.

We've always had laptops because until we moved into the new house, we've never had a dedicated study - so always shuffling between spare room and living room as needed. This time around I hadn't actually thought about getting a PC, and was pretty close to ordering a new laptop when it I thought... why not?

One thing I learned - again - is that buying a laptop is far less complicated than buying a PC. All told, I spent nearly a month getting my head around the latest and greatest in PC hardware. Along the way I discovered PCPartPicker (great site), did a heap of research, waited (im)patiently for all the parts to arrive, built it (without frying or destroying anything), and am now a happy desktop owner, again.

The goal was a beefy PC with lots of memory, running Linux. A solid development machine, not a gaming machine, but with a 'you never know' at the back of my mind. I ended up with an AMD Ryzen 1700 (I'm a sucker for an underdog, but Ryzens are well and truly impressive), and a workable graphics card (because you never know...) and my first ever SSD, and 32GB memory (a decent whack of memory - not as decent as 64GB, but 64GB at today's prices is pure madness).

The main thrill of the Ryzen is 8 cores, 16 threads. Overkill? Maybe. The dream is me doing dev work on the machine, a couple of VMs running, with the eldest logged in remotely and playing MineCraft, without me even noticing.

Oh, and a case with a glass panel, so that my sons (of course), can see the LEDs from the motherboard and CPU. I don't remember those from 11 years ago.

{2017.10.14 23:17}

Kotlin Properties

A minor Kotlin annoyance. If you have a Java class with a public final field, such that you just reference it as foo.bar, then it'd be nice for a Kotlin equivalent to be accessible in the same way.

Problem is, Kotlin/Java interop converts that to Java Bean style, so a Kotlin foo.bar has to be accessed as foo.getBar() from Java code. I was tearing my hear out wondering why the compiler thought the field I was accessing had 'private access' when it so obviously didn't.

Upshot: cue some editing when converting Java classes to Kotlin.

Probably not a huge issue for most 'idiomatic' Java, but I've long been a fan of exposing immutable fields for struct-ish types this way (subject to usual public API caveats etc; it's trivially easy for internal-only code to be refactored into method accessors if you ever need it, and in the meantime, you have cleaner code, cf. any language which supports properties).

{2017.09.14 18:35}

Thoughts on Kotlin

Living on the edge, throwing caution to the wind, a walk on the wild side and all that, I decided to git checkout -b and give Kotlin a try on a personal budgeting app I use and occasionally tweak. I'll probably update this as I go along:

  • big win: able to start adding Kotlin code to an existing Java project with a few slabs of xml in pom.xml. Java code calling Kotlin classes in the same project and vice versa, inheritance in both directions. Brilliant.

  • C# features that I'm enjoying: extension methods, properties, named parameters, default parameters, var (and even better than C#, val).

  • C# features not there, which aren't a big deal but will be really welcome if Project Valhalla delivers for the JVM: value types and better generics.

  • the whole primary and secondary constructor thing reminds me of my foray into Scala. I'm still ambivalent about it, but trying to be open-minded. Where it gets messy is that suddenly you don't have the cleaner, Java-typical statics-then-instance, publics-then-privates and finals-then-mutable ordering of fields at the top of your class. There's presumably an idiomatic way of doing this, I just don't know it yet. I wonder whether the C++ tendency to keep privates and consts at the bottom of the file make more sense.

  • top-level functions. Great idea, and why not?

  • sad: why not save developers the RSI and call it Bool?

  • sad: no unsigned types. There's a post on the Kotlin forum where Jetbrains say "yes it would be nice but it's many many months of work".

  • the open question for me is always the extent to which the compiler can bypass boxing to get things done. This may not matter for lots of things but for serious performance, it matters (in the same vein in which your average "use BigDecimal dammit" responders on SO rather betray the kinds of systems they don't work on).

  • typealias is a nice idea, but if it was as strict as a typedef it'd be even better.

  • I like the fact that Kotlin re-uses and extends the Java libraries, rather than trying to reimplement everything.

{2017.08.09 11:42}

Kotlin

Steve Yegge says it's cool.

I first noticed Kotlin a year or two ago. I was doing some Java dev at home and thought "this sucks, I really wish I had C# features on the JVM". I ended up reading about Xtend (Eclipse world) and Kotlin (Intellij world). When confronted with a new library or language, my first question is always "will I be able to compile or upgrade this in 10 years' time?". Many of my pet projects at home have been kicking around for that long or longer, and I've no shortage of fun things I'd rather be doing than migrating old code.

So, will Kotlin take off? Compared to some of the possibly-the-next-big-thing languages I've looked at over the years, Kotlin seems... different. I can't say why I think that. The fact that Jetbrains is behind it might be the thing that makes the difference. Maybe.

{2017.08.05 23:22}

NTFS permissions

For my own reference, I keep forgetting:

Take ownership of everything:

takeown /R /F *

Reset permissions:

icacls * /T /Q /C /RESET

(all via)

{2017.08.01 20:31}

mp3

Mp3 died and nobody noticed.

I'm old enough to remember when people were buying new PCs and they were "powerful enough to play mp3s".

{2017.05.17 22:30}

Flashing my Nexus 7

I did a complete re-install of my years-old Nexus 7 2012 this morning after it choked on an upgrade and got stuck at boot time. Notes for posterity:

Links and downloads:

  • instructions from this page.
  • adb and fastboot: Google now release 'latest' packages so dodgy scripts on the net are no longer needed (announcement, direct).
  • download images directly from Google (I went with nakasi 5.1.1. If it remains sluggish may go back to Kit Kat).

Then:

  • unzipped adb and fastboot into c:/android-sdk/platform-tools. I don't imagine location has to be that, but that's what the instructions said so I went with it

  • unzip image and make sure files are in same directory (ie. same dir as fastboot.exe).

  • reboot Nexus into boot loader (power off, then hold Volume Down while pressing power button).

  • plug in USB cable

  • open command prompt in the platform-tools dir.

  • run the following:

      fastboot erase boot
      fastboot erase cache
      fastboot erase recovery
      fastboot erase system
      fastboot erase userdata
      fastboot oem unlock 
      fastboot flash bootloader bootloader-grouper-4.23.img 
      fastboot reboot-bootloader 
      fastboot -w update image-nakasi-lmy47v.zip
    
  • reboot into bootloader again

  • run

      fastboot oem lock
    
  • reboot.

Worked like a charm for me. Full output:

C:\android-sdk\platform-tools>fastboot erase boot
< waiting for any device >
erasing 'boot'...
OKAY [  0.080s]
finished. total time: 0.085s

C:\android-sdk\platform-tools>fastboot erase cache
******** Did you mean to fastboot format this ext4 partition?
erasing 'cache'...
OKAY [  0.116s]
finished. total time: 0.119s

C:\android-sdk\platform-tools>fastboot erase recovery
erasing 'recovery'...
OKAY [  0.026s]
finished. total time: 0.028s

C:\android-sdk\platform-tools>fastboot erase system
******** Did you mean to fastboot format this ext4 partition?
erasing 'system'...
OKAY [  0.558s]
finished. total time: 0.560s

C:\android-sdk\platform-tools>fastboot erase userdata
******** Did you mean to fastboot format this ext4 partition?
erasing 'userdata'...
OKAY [  7.542s]
finished. total time: 7.544s

C:\android-sdk\platform-tools>fastboot oem unlock
...
(bootloader) erasing userdata...
(bootloader) erasing userdata done
(bootloader) erasing cache...
(bootloader) erasing cache done
(bootloader) unlocking...
(bootloader) Bootloader is unlocked now.
OKAY [ 25.253s]
finished. total time: 25.256s

C:\android-sdk\platform-tools>fastboot flash bootloader bootloader-grouper-4.23.img
target didn't report max-download-size
sending 'bootloader' (2100 KB)...
OKAY [  0.275s]
writing 'bootloader'...
OKAY [  1.234s]
finished. total time: 1.513s

C:\android-sdk\platform-tools>fastboot reboot-bootloader
rebooting into bootloader...
OKAY [  0.015s]
finished. total time: 0.017s

C:\android-sdk\platform-tools>fastboot -w update image-nakasi-lmy47v.zip
target didn't report max-download-size
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
archive does not contain 'vendor.img'
wiping userdata...
Creating filesystem with parameters:
    Size: 30080499712
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8160
    Inode size: 256
    Journal blocks: 32768
    Label:
    Blocks: 7343872
    Block groups: 225
    Reserved block group size: 1024
Created filesystem with 11/1836000 inodes and 159268/7343872 blocks
wiping cache...
Creating filesystem with parameters:
    Size: 464519168
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 7088
    Inode size: 256
    Journal blocks: 1772
    Label:
    Blocks: 113408
    Block groups: 4
    Reserved block group size: 31
Created filesystem with 11/28352 inodes and 3654/113408 blocks
--------------------------------------------
Bootloader Version...: 4.23
Baseband Version.....: N/A
Serial Number........: 015d25785843f405
--------------------------------------------
checking product...
OKAY [  0.031s]
checking version-bootloader...
OKAY [  0.017s]
sending 'boot' (5184 KB)...
OKAY [  0.662s]
writing 'boot'...
OKAY [  0.217s]
sending 'recovery' (5738 KB)...
OKAY [  0.736s]
writing 'recovery'...
OKAY [  0.238s]
erasing 'system'...
OKAY [  0.115s]
sending 'system' (649455 KB)...
OKAY [ 81.590s]
writing 'system'...
OKAY [ 36.336s]
erasing 'userdata'...
OKAY [  4.909s]
sending 'userdata' (139157 KB)...
OKAY [ 17.318s]
writing 'userdata'...
OKAY [ 12.632s]
erasing 'cache'...
OKAY [  0.089s]
sending 'cache' (9052 KB)...
OKAY [  1.141s]
writing 'cache'...
OKAY [  1.080s]
rebooting...

finished. total time: 157.261s

C:\android-sdk\platform-tools>fastboot oem lock
...
(bootloader) Bootloader is locked now.
OKAY [  1.430s]
finished. total time: 1.433s

C:\android-sdk\platform-tools>

{2017.01.08 13:02}

Encoding is never fun

I noticed some weird behaviour with my blog app. I had a special character in one of my entries which was being converted correctly if I ran the blog builder app from my IDE, but didn't if I ran it from the command line (or more correctly, cygwin).

After some googling, I came across this SO post. The upshot is that Java's FileWriter is sucky and just takes the default encoding from your environment, and you always want an OutputStreamWriter with the encoding explicitly set.

Another subtlety is that using a CharSetEncoder will cause encoding exceptions to be caught and thrown, just specifying "UTF-8" as the argument for the encoding will cause exceptions to be suppressed.

You can also specify -Dfile.encoding=UTF-8 on the command line, although who wants to do that?

{2016.08.20 09:53}

Bitkeeper

I saw this today, by accident: Bitkeeper's gone open source.

That's some irony, right there.

{2016.05.31 21:22}

Actually

About an hour after posting the previous entry, I thought 'sod it' and decided to push some stuff, to wit: a util library and my blog software.

{2016.04.23 16:50}

Git Hosting

I have a Github account, but there's (currently) nothing there. Mainly because I'm too lazy to clean up and review and publish code I don't mind being public.

I also have a BitBucket account, and there's (currently) nothing public there either. Mainly for the same reason that I don't have anything public at Github.

The difference being that I've recently started pushing private code to Bitbucket, because unlike Github, Bitbucket allows private repos for free.

Then today I came across GitLab. Now I have an account there too. It too allows private repos.

I'm a little old-skool and I'm still making peace with the idea of having my 'private' coded hosted externally. I mean, I still pre-encrypt my stuff before letting cloud backups do their own encrypting and syncing. But in reality, my 'private' code is stuff like Project Euler, and apps I use at home, which are generally a bit ugly or hard-coded for me. I don't want them shared by default but it's not the end of the world if they got 'leaked' in future. The main thing I gain is easy backing up of my code. Which I sort of have anyway with my encrypty-cloud backup, but restoring and accessing that isn't so easy.

The two other reasons for remote hosting are visibility (aka helping the world, and/or ego), and code management features.

As for 'visibility' - I think Github's still the only place to publish code, should you want your work to be seen. I'll get around to publishing stuff publically by default, eventually, since ... well, why not? Yet none of the pet projects I'm working on are likely to be of interest to anyone else in the world, and since I don't think anything I work on at home is necessarily CV-enhancing (beyond 'does he write crap code?'), I'm not that fussed about visibility.

Finally, code management features. Community features (patches, merges, etc) in Github are great, but I don't need them for private code. I'm curious to see what Bitbucket (and, probably, Gitlab) will give me. Issue tracking and the like? Code searching? CI (Gitlab, I think?). It'll be interesting to see what's useful and/or interesting.

{2016.04.16 09:47}

« Older | Newer »