October 15, 2015

How Spotify got my attention with their culture

I could say a whole lot of things.. but I don't think I need to.

Just watch..




July 19, 2015

Do you know the Joel Test? You should.

Joel Spolsky understood that the SEMA test was overengineering.

So he did his own test. Guess what? It's really quite nice.

The Joel Test
  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?
It's a good way to do a unambiguous test on your own company and it's current philosophy. 

You can read more about it here.


So.. what was your company score?


July 7, 2015

Google Developers Group - Porto, Portugal


I've been silent for some time, as I've been a bit occupied doing something new that I think will be awesome.

I've just co-created the Google Developers Group @ Porto.

You don't know what a GDG is?




You'll hear more from me about this soon. We're planning some - hopefully awesome - things!

#GDGPorto 

June 24, 2015

Work Rules

Again, a masterpiece from the Google guys (in this case just one guy).



This is an awesome deep view on how Google People's Operations work and why they work the way they do.

Together with the book "How Google Works" that I've mentioned here before, it's a culture and procedure pool that shows that it's worth rethinking how everything is normally done at a company.


SPOILERS AHEAD.






Also a quick overview ("stolen" from a review @ Amazon):

- Operate on the belief that people are fundamentally good
- Use groups of peers or independent teams for: hiring, promotions, salary increases, awards, and firing (often excluding the direct manager)
- Managers exist to: (a) make tie-breaking decisions (b) coach/train to develop employees (c) care about people's well-being (d) set vision/strategy (e) provide technical advice (f) empower by clearing roadblocks
- Conduct 2x-per-year performance reviews on a 5-point scale and then calibrate (which are separate from continuous feedback); get 360 feedback on ‘do more of’ and ‘do differently’ 1x per year
- Make all goals (objectives and key results) public
- Design physical spaces to encourage interaction across departments
- Help employees meet the people they are helping
- Ensure transparency (in all matters unless unlawful)
- Only hire people who are better than you, who will be successful in the context of your organization, and who will make everyone around them more successful
- Referrals from existing employees are the best source of candidates
- Couple assessments of cognitive/problem-solving/learning ability, conscientiousness, and emergent leadership/fit with structured interviews that are job related: (a) Tell me about a time..? (b) What would you do if…? Note: 4 interviews are sufficient
- Eliminate status symbols
- Pay bonuses based on the median salary of all people in a job
- Have people who are the best at something train everyone else (share principles, role-play, discuss, review video of role-play)
- Make pay commensurate with contribution (following a power law rather than a normal distribution)
- Provide experiential rewards (as a complement to monetary awards)
- Celebrate accomplishment with public recognition
- Reward smart failure and make sure to conduct “what did we learn?” post-mortem sessions
- Provide nudges to influence, not dictate, choice
- Uphold the obligation to dissent (a McKinsey core value)
- Treasure the weird
- Put more wood behind fewer arrows
- Building a great culture requires constant experimentation and renewal

Various programs and processes:
- TGIF: weekly all company meeting to share updates plus 30 minutes of Q&A
- Dogfooding: Have employees test new products and provide feedback before piloting with customer
- Bureaucracy Busters: annual program to identify and fix biggest frustrations
- Upward Feedback Survey: 2x per year survey about manager quality
- 20 Percent time: time for people to engage in side-projects (often 120% time)
- Googlegeist: Annual survey focused heavily on innovation, execution, and retention
- Tech Advisor: network of experienced leaders offering confidential, one-on-one office hours
- Random Lunches: set people up with others they don’t yet know
- Tech Talks: Employees sharing work (and non-work) expertise
- Talks at Google: Outsider (ex: authors, business leaders, entertainers, etc.) sharing their wisdom

May 5, 2015

Android: Debug an ANR



There are common mistakes on Android apps that make you have Application Not Responding (ANR) dialogs.

Something like:



Normally it means that either:

  • your UI/main thread is taking more time that it is supposed to doing something (yes, I'm looking at you that are doing network operations on UI/main thread) 
  • or a less common a BroadcastReceiver is taking more than 10s processing.

A good way to try to detect the problem is by fetching the file /data/anr/traces.txt which is generated after a ANR happens on a device (beware that it is overridden after another ANR happens).

You can get it (without root) by using:


adb shell "cp /data/anr/traces.txt /storage/extSdCard/" 
or

adb pull /storage/extSdCard/traces.txt


That offers you a overview of what each thread was doing at the time of the ANR.

Something like:

----- pid 6996 at 2015-01-01 01:01:01 -----
Cmd line: com.example.app

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)

"main" prio=5 tid=1 MONITOR
  | group="main" sCount=1 dsCount=0 obj=0x41772508 self=0x41762988
  | sysTid=6992 nice=0 sched=0/0 cgrp=apps handle=1074810672
  | schedstat=( 1682006857 678192128 2118 ) utm=138 stm=29 core=1
  at com.example.app.services.MyService.doStuff(MyService.java:~229)
  - waiting to lock <0x42ad0818> (a com.example.app.services.MyService) held by tid=29 (ThreadPool[#1/1])
  at com.example.app.services.MyService$MyServiceBinder.start(MyService.java:1552)
  at com.example.app.managers.MyManager$1.onServiceConnected(MyManager.java:311)
  at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1097)
  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1114)
  at android.os.Handler.handleCallback(Handler.java:615)
  at android.os.Handler.dispatchMessage(Handler.java:92)
  at android.os.Looper.loop(Looper.java:137)
  at android.app.ActivityThread.main(ActivityThread.java:4918)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:511)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
  at dalvik.system.NativeStart.main(Native Method)

"Binder_5" prio=5 tid=36 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x42dc9328 self=0x5492f280
  | sysTid=7096 nice=0 sched=0/0 cgrp=apps handle=1418217512
  | schedstat=( 3540036 12268069 85 ) utm=0 stm=0 core=1
  #00  pc 0000cba0  /system/lib/libc.so (__ioctl+8)
  #01  pc 00027ee5  /system/lib/libc.so (ioctl+16)
  #02  pc 00016bfd  /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+124)
  #03  pc 000173af  /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+154)
  #04  pc 0001b171  /system/lib/libbinder.so
  #05  pc 0001104f  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+114)
  #06  pc 0004b6f3  /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+66)
  #07  pc 00010bb5  /system/lib/libutils.so
  #08  pc 00012d20  /system/lib/libc.so (__thread_entry+48)
  #09  pc 00012478  /system/lib/libc.so (pthread_create+172)
  at dalvik.system.NativeStart.run(Native Method)

By this ANR log you should look at MyService.java:~229 for your problem!

So...






March 23, 2015

Android Trivia: Fragment Attachment



Imagine that:

You have a FragmentActivity which has a Drawer and the fragment attachment order was:

- Drawer
- Fragment A
- Fragment B.

Note: By order I mean that I'm adding the fragments on a list by the order that each is received on onAttachFragment. So when entering the Activity A, the order was the one above.


Imagine that you go to background, and you Activity A is killed, and when you reopen the app it restores its state. 

Do you know what the attachment order will be?

- Fragment A
- Fragment B
- Drawer


Yes. The Drawer will be the last. So if you are maintaining some of your own stack order using the Fragments lifecycle beware!






March 20, 2015

Android Trivia: Differences between the Activity and the Fragment Lifecycle




Imagine that you are going from Activity A to Activity B (via startActivity).

Imagine than after it, on Activity B you replace Fragment A for Fragment B.

Most developers when starting  imagine a very similar lifecycle between the 2 operations, due to the similar method names.


Well...


Activities

A -> B

Activity A: onCreate
Activity A: onCreate
Activity A: onStart
Activity A: onPostCreate
Activity A: onResume
Activity A: onResumeFragments
Activity A: onPostResume
Activity A: onPause
Activity A: onResume
Activity A: onResumeFragments
Activity A: onPostResume
Activity A: onPause
Activity B: onCreate
Activity B: onAttachFragment
Activity B: onStart
Activity B: onPostCreate
Activity B: onResume
Activity B: onResumeFragments
Activity B: onAttachFragment
Activity B: onPostResume

B -> A

Activity A: onStop
Activity A: onDestroy
...
Fragments

A -> B 

Fragment A: Attaching.
Fragment A: onCreate
Fragment A: onResume
Fragment A: onPause
Fragment A: onStop
Fragment A: onDestroyView
Fragment B: Attaching.
Fragment B: onCreate
Fragment B: onResume
Fragment B: onPause
Fragment B: onStop
Fragment B: onDestroyView
Fragment B: onDestroy
Fragment B: Detaching.







B -> A

Fragment A: onResume
...




Don't miss the overlap on the Activities and the lack of it on the Fragments, or you may develop some code that doesn't work as you except.



February 28, 2015

Android Central Dispatch

I introduce you my new pet: Android Central Dispatch





I'll update this post briefly with more info :-) 

February 23, 2015

Android Trivia: Method limit



Did you know that there is a maximum number of Java class methods on Android

Yes, it's 65k

Well in fact, now there's a solution for that... but do you really need more then 65k methods?! 




February 19, 2015

Android: onDowngrade... the dark path on databases



So I've been developing an app which has a really big database (for an Android app) and while still in development it has already been upgraded quite a few times.

My team and I have been using the onUpgrade method without any problems for the whole time, but because we use git with one branch per feature and code reviews sometimes the app version that we have installed on our device before when doing a code review is bigger that the one of the next code review.

That isn't of course a problem, we could just uninstall it, as it will never happen in production, but for my knowledge sake, I tried to implement a simple downgrade.. just drop all tables and create them again.

So I've went to read the javadoc:

public void onDowngrade (SQLiteDatabase db, int oldVersion, int newVersion)

Added in API level 11
Called when the database needs to be downgraded. This is strictly similar to onUpgrade(SQLiteDatabase, int, int) method, but is called whenever current version is newer than requested one. However, this method is not abstract, so it is not mandatory for a customer to implement it. If not overridden, default implementation will reject downgrade and throws SQLiteException
This method executes within a transaction. If an exception is thrown, all changes will automatically be rolled back.
Parameters
dbThe database.
oldVersionThe old database version.
newVersionThe new database version.



Ok, so I've had to override it to avoid an exception. No problem...


... I thought.


In fact the app crashed when I tried to drop all tables and (re)create them on that method... it seemed strange, as it was a lock on the database problem...

(I'll later add here the stack trace)


So after quite a bit of googling/stackoverflowing I've found a bizarre, but working answer.

Which made me class (after stripped of all my app-business-logic) look like this:

public abstract class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context, String name, CursorFactory factory, int version,            DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {        super(context, name, factory, version);
    }

    @Override
    public synchronized SQLiteDatabase getWritableDatabase() {
        try {
            return super.getWritableDatabase();
        } catch (SQLiteDowngradeFailedException e) {
            // do some magic...            dropAllTables();
            createTables();
        }


        // now return a freshly created database
        return super.getWritableDatabase();
    }

    @Override
    public final void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // throwing a custom Exception to catch it in getWritableDatabase
        throw new SQLiteDowngradeFailedException();
    }

    // that's the exception
    static class SQLiteDowngradeFailedException extends SQLiteException {
        public SQLiteDowngradeFailedException() {}

        public SQLiteDowngradeFailedException(String error) {
            super(error);
        }
    }
}

I fell a bit like Thor (in a bad way) hitting the code with a hammer until it works... but I haven't found a more elegant solution.

I really think that the Android team should change this behavior as it doesn't seems to make sense if you really need to downgrade a database... but until then, if anyone needs a solution, here it is.

If anyone has solved this with at least a "smaller hammer", please share I'd really appreciate!

If not.. if you need this at least you have found a solution.

February 5, 2015

How Google Works



I've just finished reading How Google Works. It could be just one more of those books about a company that just focus on the stories and on the OMGs how spectacularly awesome this company is, but I was really surprise to find it one of the best books about real management that I've read recently.

It does not focus only on how Google works but why it works in specific ways, providing the background mindset of the management which is a fresh breeze of air on management.

It deprecates the old management style of "I'm the boss and I know everything" to a more 21st century If I hire the best (and I have to give my best to hire them), I'll have to give up some of the pyramidal control in exchange to tap into the power of each of the brilliant individuals that are now working in this company.

I'll leave here some of the parts I've really appreciated:

(Speaking about smart creatives, which is the kind of workers Google wants to hire:) It is also why they are uniquely difficult to manage, especially under old models, because no matter how hard you try, you can't tell people like that how to think. If you can't tell someone how to think, then you have to learn to manage the environment where they think. And make it a place where they want to come every day.

Many people, when considering a job, are primarily concerned with their role and responsibilities, the company’s track record, the industry, and compensation. Further down on that list, probably somewhere between “length of commute” and “quality of coffee in the kitchen,” comes culture. Smart creatives, though, place culture at the top of the list. To be effective, they need to care about the place they work. This is why, when starting a new company or initiative, culture is the most important thing to consider.

Companies come up with elaborate, often passive-aggressive ways to say no: processes to follow, approvals to get, meetings to attend. No is like a tiny death to smart creatives. No is a signal that the company has lost its start-up verve, that it’s too corporate. Enough no’s, and smart creatives stop asking and start heading to the exits.

Twenty percent time is a check and balance on imperial managers, a way to give people permission to work on stuff they aren’t supposed to work on. It helps bring to life the Steve Jobs maxim that “you have to be run by ideas, not hierarchy.

You want to invest in the people who are going to do what they think is right, whether or not you give them permission. You’ll find that those people will usually be your best smart creatives.

Over time I’ve learned, surprisingly, that it’s tremendously hard to get teams to be super ambitious. It turns out most people haven’t been educated in this kind of moonshot thinking. They tend to assume that things are impossible, rather than starting from real-world physics and figuring out what’s actually possible. It’s why we’ve put so much energy into hiring independent thinkers at Google, and setting big goals. Because if you hire the right people and have big enough dreams, you’ll usually get there. And even if you fail, you’ll probably learn something important. It’s also true that many companies get comfortable doing what they have always done, with a few incremental changes. This kind of incrementalism leads to irrelevance over time, especially in technology, because change tends to be revolutionary not evolutionary. So you need to force yourself to place big bets on the future.

Unfortunately, like Jonathan’s failed gate-based product development framework, most management processes in place at companies today are designed with something else in mind. They were devised over a century ago, at a time when mistakes were expensive and only the top executives had comprehensive information, and their primary objectives are lowering risk and ensuring that decisions are made only by the few executives with lots of information. In this traditional command-and-control structure, data flows up to the executives from all over the organization, and decisions subsequently flow down. This approach is designed to slow things down, and it accomplishes the task very well. Meaning that at the very moment when businesses must permanently accelerate, their architecture is working against them.

The tendency of a CEO, (...), is to try to make too big an impact. It is hard to check that CEO ego at the door and let others make decisions, but that is precisely what needs to be done.

We call it the rule of seven. We’ve worked at other companies with a rule of seven, but in all of those cases the rule meant that managers were allowed a maximum of seven direct reports. The Google version suggests that managers have a minimum of seven direct reports (Jonathan usually had fifteen to twenty when he ran the Google product team). We still have formal organization charts, but the rule (which is really more of a guideline, since there are exceptions) forces flatter charts with less managerial oversight and more employee freedom.


“Tom Peters: There is no such thing as a minor lapse of integrity” 


If you are now curious, you can have here a little sneak peek about what they talk about on the book.

February 3, 2015

EventBus, my way.

One of my favorite libraries for Android recently has been EventBus. If you don't know what it is, it is simple, according to their own explanation:


EventBus is publish/subscribe event bus optimized for Android.




    • simplifies the communication between components
    • decouples event senders and receivers
    • performs well with Activities, Fragments, and background threads
    • avoids complex and error-prone dependencies and life cycle issues
    • makes your code simpler
    • is fast
    • is tiny (<50k jar)
    • is proven in practice by apps with 100,000,000+ installs
    • has advanced features like delivery threads, subscriber priorities, etc


I've been using it on my Android architecture examples and it works like a charm. The only thing I've been missing is the capability to limit the number or running events and the capability of cancelling them.

So.. I've fork it, and I'm now actively integrating that capability on the library. I'll probably make a pull request upstream to the original EventBus but I don't have any clue if it will be accepted or not.

Anyway... if you find it useful give it a look.. and who knows, give a line or two of code also!