Ranked 10000 in Code Jam 2021 Qualification, Perl + Scala + Dart

I spent the Saturday competing in Google Code Jam 2021 qualification round, and earned a well-rounded rank: exactly 10000.

yoursunny rank 10000

Code Jam is about Algorithms

My first time competing in Code Jam was 2012. I heard about Code Jam earlier that year, from a flyer posted by the ACM student chapter at University of Arizona. Since then, I participated in Code Jam every year, and 2021 is my 10th year competing in Code Jam.

Code Jam isn't about code or jam, but about mathematics and algorithms. Although I'm a good network programmer and write a lot of production quality code, I struggle at algorithms especially when I'm under a time pressure. Nevertheless, I continued competing in this annual event, so that I can remember the last bits of algorithms, and occasionally learn a few new tricks by reading through the post-round analyses.

yoursunny.com is Served by Caddy

The last rebuild of yoursunny.com was in Spring 2017, when I moved the whole website into git repositories. It's been more than 3 years, and I think I should share an update on a few changes in the stack that serves this website.

History of HTTP Servers Behind yoursunny.com

Since 2011, my HTTP server of choice was lighttpd. Then, I have PHP running in FastCGI mode to serve the dynamic pages. It works, but I don't really like the lighttpd's script-like configuration structure. Moreover, there were suspected memory leaks in my setup, so that I had to use a cron job to restart the HTTP server weekly.

I keep hearing good words about nginx, as well as the benefits of running PHP in FPM mode. In 2013, I made the switch to nginx and PHP-FPM. The declarative configuration of nginx is easy to understand and makes sense to me.

HTTPS came to yoursunny.com at the end of 2015. Like many other websites, the TLS certificates were issued by Let's Encrypt, and requested through certbot command line client. One problem is that, my VPS at the time had only 64MB memory, and certbot would not work in such a small amount of memory. I had to request the TLS certificate on my laptop, and then upload it to the VPS.

Alexa, ask UA Campus Rec when does the gym open?

I built an Alexa Skill, and got it published.

How I Learned Alexa Skill Kit and Why I Picked it Up Again

I learned about Alexa Skill Kit at Hack Arizona 2017, and built an incredibly complicated 520bus skill to query departure times of Sun Tran buses and Sun Link modern streetcar. I didn't win a prize, and quickly forgot about that.

A few months later, a tweet caught my attention: publish a skill, get an Echo Dot & Alexa dev swag. I always wanted to own a hardware device that integrates with Alexa. I considered the "practically free" Dash Wand, but gave up when I found out it is powered by batteries. I couldn't afford to buy an Echo, because I already spent all my money on those ESP8266 toys. However, I'm not going to miss a FREE Echo Dot.

How to Deduplicate BibTeX Entries?

I'm writing my dissertation recently. My dissertation is a combination of several publications from my PhD career. Therefore, part of my dissertation writing process involves copy-pasting the papers together into a single document.

Like any good academics, I typeset my publications with LaTeX, and use BibTeX to incorporate citations into the documents. My collection of bibliographies is fairly ad hoc: during each writing project, I search for related work to cite in my paper. Unlike most others, I create a separate bib file for each BibTeX entry named after the citation key. For example, I would have bib/ndn-tlv.bib for a BibTeX entry named "ndn-tlv", and bib/Mininet.bib for the "Mininet" entry. This allows me to find available citation keys with a quick glance over the bib/ directory. My build process then concatenates these small bib files into ref.bib as an input to BibTeX.

My dissertation combines all my publications, and thus needs a union of BibTeX entries from those combinations. To make this union, I can copy all these single-entry bib files into the same directory. If two previous papers cited the same reference, their bib files should have the same name, and only one copy would be left in the combined directory.

Except that the above assumption is true only if I cited the same reference with the same citation key. And so I discovered a citation appearing twice in my dissertation:

duplicate references in dissertation

yoursunny.com is in Git and Completely Rebuilt

I started making websites since 2001. This website, yoursunny.com, started in 2006. In the past 11 years, I've rebuilt the site several times, switched from ASP to PHP, and moved from Windows dedicated hosting to shared hosting and eventually to Linux VPS. So far, every time I want to perform a major edit to the website, I copy original versions of affected files to a backup folder on my computer, and then go ahead to do the edit. After having tested the modification locally, I upload changed files via FTP or SFTP to the server. One constant worry over my head is, what if I lose all the files on my computer, and my hosting provider vanishes so I can't get them back? Another headache is, sometimes I may make an edit incorrectly, but I couldn't revert it back because I didn't copy the original files to the backup folder as I determined the change wasn't "major" enough to warrant a backup.

During my studies at University of Arizona, I learned a useful tool called git. Git is a source control system: it allows developers to create a repository and put source code into the repository, and will automatically keep track of all the edits applied to each file. By putting website source code into a git repository, I can find out what modifications I've performed to each file over time, regardless of whether it is "major" or "minor". Additionally, I can synchronize the git repository with a remote git server, so that the server has a copy of my website, including edit histories as well. This would solve both the worry of losing files, and the headache of not having an earlier version to revert to in case of an incorrect modification.

After delaying this projects several times, I am finally determined to move yoursunny.com into git repositories in Apr 2017. At the same time, to keep the website source code as clean as possible, I decide to try out two new technologies: static site generators and Composer. That is, I would rebuild yoursunny.com, copying page by page, into a new website stored in git repositories.

I spent about 2 months for this rebuild/move, and I'm happy to announce that yoursunny.com is now under source control.

Main Site with Composer






require 'qqwry.lib.php';
$qqwry=new QQWRY;
foreach ($results as $ip=>$record) {
    echo long2ip($ip).' '.$record->get_c().' '.$record->get_a()."\n";











  • 能运行PHP的Web服务器,例如 Apache 或 IIS
  • wget.exe命令行客户端 或 浏览器
  • 具备PHP语法高亮功能的文本编辑器,例如 Notepad2





关键词 P2P,流量,监控,网络,l7filter


Fast growth of Peer-to-Peer traffic are taking more and more backbone network bandwidth, and may slow down key businesses. In this paper, major P2P identification techniques and a way to enhance them are introduced at first. Then we set up a P2P traffic detection router based on iptables and l7filter. A Web application is designed and implemented with AJAX and PHP, so that a network administrator can manage the router or view router logs in this Web application. The router and the Web application make up a P2P detection system.



class dbMySQL {//数据源访问类
    private $conn;//连接
    private $prefix;//表名前缀
    private $sql=NULL;//上一条SQL语句
    private $result=NULL;//结果
    private $rows=0;//行数
    private $rows_got=0;//已提取行数
    //$db=new dbMySQL(主机,用户名,密码,数据库名,表名前缀,是否永久连接);
    function __construct($host,$username,$password,$dbname,$prefix='',$pconnect=TRUE) {//连接
        $this->conn=@$connect_function($host,$username,$password) or die('不能连接到MySQL数据源服务');
        mysql_query("SET NAMES 'utf8'",$this->conn);
        @mysql_select_db($dbname,$this->conn) or die('MySQL数据源中数据库不存在');
    private function close() {//如果上一个结果存在,清除它
        if ($this->result!=NULL) mysql_free_result($this->result);
    public function execute_sql($SQL) {//执行
        //echo $SQL;
        $err=mysql_error($this->conn); if ($err!='') die($err);
    public function execute($SQL,$p=NULL,$prefix='###') {//带参数执行
        if ($p==NULL) { $this->execute_sql($s); return; }
        foreach ($p as $i => $v) {
            if (ctype_digit($i{0}) && !is_numeric($v)) die('SQL数值型参数错误 '.$i.'=>'.$v);
    //数组$p "a"->"ppp"
    //SELECT * FROM j WHERE m=?a 解析为 SELECT * FROM j WHERE m='ppp'ִ
    //$prefix表示前缀占位符,默认###,FROM ###kk在前缀是pr_时解析为FROM pr_kk
    public function query_sql($SQL) {//查询
        //echo $SQL;
        $err=mysql_error($this->conn); if ($err!='') die($err);
    public function query($SQL,$p=NULL,$prefix='###') {//带参数查询
        if ($p==NULL) { $this->query_sql($s); return; }
        foreach ($p as $i => $v) {
            if (ctype_digit($i{0}) && !is_numeric($v)) die('SQL数值型参数错误 '.$i.'=>'.$v);
    public function read() {//提取一行为关联数组,如果已提取完则返回NULL
        if ($this->result==NULL) return NULL;
        if ($this->rows_got==$this->rows) return NULL;
        return mysql_fetch_assoc($this->result);
    public function num_rows() {//总行数
        return $this->rows;
    public function eof() {//是否提取完了?
        return ($this->rows_got==$this->rows);


  • 高安全性:强制检查类型、自动转义,避免SQL注入漏洞
  • 方便编程:面向对象语法,不必写mysql_fetch_assoc等长长的函数名
  • 方便编程:仿reader机制,直接从对象读出数据,不必再写$resultID
  • 支持表名前缀:允许在一个数据库中运行多个应用