Profile cover photo
Profile photo
Lishi He
Brilliant Melody
Brilliant Melody

Lishi's posts

Post has attachment

Post has attachment

Post has shared content
What I learned about mobile in China

In China I met several entrepreneurs and others at the Bluetooth World conference there. China has a very different mobile culture, so thought I'd share what I learned here:

1. Facebook and Twitter and many other sites don't work. Neither do their mobile apps. Yes, you can use a VPN or a proxy server, but most sites are very slow compared to when I use those sites in the US. (The government blocks those sites. Most of the entrepreneurs I talked with said the government does that to protect local businesses and their own pocketbooks).

2. Almost every high-end user had an iPhone. Others had Android. I never saw Windows Phone or Blackberry's being used. Android is coming on strong, everyone admits.

3. Every iPhone was jailbroken. Why? Because using the Apple App Store is painful at best and totally unusable at worst. Why? The speed of downloading apps from Apple is horrid. So, everyone makes their phone have a Chinese app store so they can download apps fast. That means Apple will see lower revenue per device than it does in the states, where it can sell movies, music, and apps directly.

4. Every service has a Chinese copy. In the shot I took below there is a YouTube copy. Actually several copies. 

5. The Chinese hate the firewall too, but they say it just means you gotta be "entrepreneurial" to get around it. Either by using Chinese copies of services you like, or by using VPNs.

6. There isn't LTE in Shanghai yet. That I thought was totally shocking, given how modern and wealthy the city is. My phones, back in San Francisco, are dramatically faster on videos and things like Waze. Everyone says that LTE finally got approval from the government and should be showing up by the end of the year.

7. There is a strong mobile culture. It felt a lot like San Francisco, with lots of apps for local food, transit, etc. Plus, the people i met with knew exactly how the local apps compared with things like Yelp or OpenTable.

8. Many apps have "offline" features. Baidu maps, for instance, aren't as accurate as Google's maps, but they work offline, which matters because of lack of LTE and also pricing plans that charge you per megabyte downloaded.

9. There are lots of low-cost Android phones and systems coming out. Think about how Facebook's new Home App takes over app launching and you are close to how these new Chinese phones take over your notifications and app screens. They also strip out all Google stuff and add in their own apps and search. 

10. Everyone knows how to get their phones customized. You can pay people to root your phones for a few dollars and load you up with the apps you want. This lets people who buy very low-end phones get similar experiences you'll get on more expensive phones.

For those of you who have visited China, or who live there (Google+ was the only social network I could use directly -- the others I used through Flipboard just fine) what other things have you noticed about how Chinese use mobile phones vs. how people in US and Europe use them?

Google Plus 的 App 成了一个图片分享工具,用去大量3G流量啊。

Post has attachment

Post has shared content
Wanted: experts in Twisted, Tornado, asyncore or other Python async APIs (greenlets/gevent, Stackless, libevent all welcome!). In we're trying to hash out the async API for the future (for the Python stdlib) and we need input from expert users of the current generation of async APIs.

Post has shared content
In fact, there is no real privacy in China.
Government grade privacy for your smartphone from founder of PGP Very honored to meet crypto expert and legend Phil Zimmermann. He created PGP, Pretty Good Privacy, most widely used email encryption software in the world. But now he's making it easier to use with Silent Circle. This system lets you talk around the globe completely securely using email, voice call, videoconference, or text messaging on mobile phones. Here get a good look at the system and talk about why many people around the world need this.

If you travel with corporate, government, or personal secrets and you want them to stay that way you should look into Silent Circle.

Post has shared content
I've gotten a fair amount of mail about a recent blog post titled "Why I'm not leaving Python for Go" [1], in which the author says that Go is great except that "errors are handled in return values". I thought it would help to write a little about why this is.

In Go, the established convention is that functions return errors; they don't panic. If a file isn't found, os.Open returns an error; it doesn't panic. If you write to a broken network connection, the net.Conn's Write method returns an error; it doesn't panic. These conditions are expected in those kinds of programs. The operation is likely to fail, and you knew that going in, because the API designer made it clear by including an error result. 

On the other hand, there are some operations that are incredibly unlikely to fail, and the context is such that there is no way to signal the failure, no way to proceed. These are what panic is for. The canonical example is that if a program evaluates x[j] but j is out of range, the code panics. An unexpected panic like this is a  serious bug in the program and by default kills it. Unfortunately, this makes it difficult to write robust, defensive servers that can, for example, cope with the occasional buggy HTTP request handler while keeping the rest of the server up and running. To address that, we introduced recover, which allows a goroutine to recover from a panic some number of call frames below. However, the cost of a panic is the loss of at least one call frame from the stack. We did this intentionally. To quote from the original mail: "This proposal differs from the usual model of exceptions as a control structure, but that is a deliberate decision.  We don't want to encourage the conflation of errors and exceptions that occur in languages such as Java."

The post I mentioned at the start asks "why is an array out of bounds any more cause for panic than a bad format string or a broken connection?" The answer is that there is no in-band way to report the error during the evaluation of x[j], while there is an in-band way to report an error in a bad format string or a broken connection. (The format string decision is interesting by itself but orthogonal to this discussion.)

The rule is simple: if your function is in any way likely to fail, it should return an error. When I'm calling some other package, if it is well written I don't have to worry about panics, except for, well, truly exceptional conditions, things I shouldn't be expected to handle.

One thing you have to keep in mind is that the target for Go is programming in the large. We like to keep programs concise, but not at an increased maintenance cost for big programs worked on by large numbers of programmers. The seductive thing about exception-based error handling is that it works great for tiny examples. But diving into a large code base and having to worry about whether every single line might, in ordinary operation, trigger an exception worth handling is a significant drag on productivity and engineer time. I have had this problem myself finding my way around large Python programs. The error returns used by Go are admittedly inconvenient to callers, but they also make the possibility of the error explicit both in the program and in the type system. While simple programs might want to just print an error and exit in all cases, it is common for more sophisticated programs to react differently depending on where the error came from, in which case the try + catch approach is actually more verbose than explicit error results. It is true that your 10-line Python program is probably more verbose in Go. Go's primary target, however, is not 10-line programs.

Raymond Chen's articles are the best exposition I've seen about the pitfalls of trying to do error handling with exceptions:
Suffice it to say that the Go developers agree: error is so important we made it a built-in type.


P.S. Occasionally you see panic and recover used as a kind of non-local goto, similar to longjmp and setjmp in C. This is fine too, but only as an internal detail of your package. If callers need to know, you're still doing it wrong.


Post has shared content
If you have a Pandora account, I highly recommend using a throwaway password for it (assuming you don't do so already).

Why? Because Pandora doesn't even one-way hash their passwords. If your account is logged in on a computer, anyone who sits down at that computer can go and look up your password on Pandora's settings page.

Attached is an image that shows what that settings page looks like upon load - I haven't manually entered anything into the form fields and I don't use Chrome's auto-fill; the text in the fields is populated by Pandora.... including the plaintext of the password.

Things like this are why I wrote a blog post about how to do web app auth correctly:

Thanks to +Dan Boger for bringing this up.


Edit: Also just discovered that their password-reset tokens aren't single use. You can reset the password of an account multiple times with the same reset token link...

Also, since Pandora allows you to just change the password field and hit "Save", if you come across someone's logged-in computer, you can just change their password even if Pandora didn't tell you what it was. (The right way to do this is to require the user to enter their current password along with the new password, and pre-fill none of the fields.)


Edit 2: It has been pointed out in the comments that even though the password itself appears to be fetched over HTTPS, the page it is inserted into is not... and thus a man-in-the-middle attack is possible to retrieve a user's password by injecting a script into the main page that reads it from the DOM, if you have control of the upstream (e.g. if you're the owner of a public wireless network or the like).

#security   #pandora

Post has attachment
Wait while more posts are being loaded