0%

csv,全称Comma-Separated Values,翻译为中文就是“逗号分隔值”(其实分隔符可以是逗号、制表符或者空格)。理解了这一点,便可以很简单的将数据导出为csv。

表格其实就是二维数组,分为列和行。例如班级表:

姓名 年龄 性别
小明 12
小芳 11

转化为csv之后的值为

1
2
3
姓名, 年龄, 性别
小明, 12, 男
小芳, 11, 女

也就是将”换列”转化为了”,”,将“换行”转化为了“\n”。

php代码也很简单:

1
2
3
4
5
6
7
8
9
10
11
$csv = "";

foreach($data as $line){
$csv .= join(",", $line) . "\n";
}

$csv = iconv("utf-8", "gb2312", $csv);

header( "Content-Disposition: attachment; filename= {$filename}.csv");

echo $csv;

php5.3中新增的特性

静态晚绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
class A {
public static function who(){
echo __CLASS__;
}

public static function test(){
         echo static::who();
}

    public static function test2(){
         echo self::who();
}
}

class B extends A{
    public static function who(){
      echo __CLASS__;
    }
}

A::test();//输出A
A::test2();//输出A

b::test();//输出B 晚期静态绑定会绑定到调用类
b::test2();//输出A 直接绑定会绑定到方法所在类

晚期静态绑定是使用static代替selfself会指向方法所在类,static会指向后期调用者。

goto支持

1
2
3
4
5
6
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
//输出Bar

当需要跳出多层循环时,必须要增加判断才可以,而goto可以直接跳出循环,与C语言类似。

三元运算简写形式

从php5.3开始支持三元运算符?:。例如$a ?: $b$a为真值返回$a,否则返回$b。其效果等同于$a ? $a : $b

1
2
3
4
5
6
7
<?php
$a = false;
$a = $a?:1;
echo $a;//输出1
$a = 1220;
$a = $a?:1;
echo $a;//输出1220

php5.6中新增的特性

const常量可以用表达式定义,const常量可以是数组

1
2
3
const ONE = 1;
const TWO = ONE + 1;//仅可以为常量的结果
const Arr = [1,2];

可以用“…”表示多个参数

1
2
3
4
5
function sum(...params){
return array_sum(params);
}
sum(1, 2, 9); //12
sum(...[1,2,9]);//12 注意:只能传数字下标数组,不能穿带有键名的数组

可以用“**”表示幂运算

1
3 ** 4; //81

快速排序的思想是分冶法。

取数组中间值=>遍历数组剩余元素=>小于中间值的放左边,大于中间值的放右边=>将左右循环如此直至不可再分->将已排好的合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$arr = [11, 17, 29, 63, 45, 97, 12, 45, 34, 91, 64, 82, 76, 22, 77, 37, 85];

function quickSort($arr)
{
    if (count($arr) <= 1) return $arr;
    $index = (int)floor(count($arr) / 2);
    $value = $arr[$index];
    array_splice($arr, $index, 1);
    $left = $right = [];
    for ($i = 0; $i < count($arr); $i++) {
        if ($arr[$i] < $value) {
            array_push($left, $arr[$i]);
        } else {
            array_push($right, $arr[$i]);
        }
    }
    $left = quickSort($left);
    $right = quickSort($right);
    array_push($left, $value);
    return array_merge($left, $right);
}

echo join(", ", quickSort($arr));

排版者应像手艺人一样遵循一条原则:做好自己的工作并隐于无形


关于

网页上百分之九十五的信息是「文字」,大多数人浏览网页的状态就是阅读,也就是你目前正在做的事情. 因此作为一名前端工程师,让文字更好地在网页显示,是一件极其重要的工作.

字体排印有两种形式,一种称为 Creative Typography,另一种称为 Technical Typography. 前者倾向于设计,比如选择的字体表达的情绪,字间距的设定带来的视觉影响. 而后者更倾向于技术,以一套有迹可循的规则进行应用,比如实现「齐头尾」如何避免中西文混排造成的字间距拉伸,以及选择什么样的 font-family 可以在多平台上最优显示等等.

本文主要围绕 Technical Typography 进行讨论.

选择字体

在 Web 上应用字体,是一门技术,同时也是一门艺术. 由于计算机历史发展的原因,西文有大量优秀的字体可供选择,可对于中文来说就是一项挑战. 主流操作系统提供的本地中文字体极少,另一方面中文字体组成的特殊性,其体积过于庞大,无法良好地使用 webfont. 所以编写健壮的 font-family 是一件需要深思熟虑的事情.

以下列出各种平台下合适的中西文字体:

Mac Windows Linux
冬青黑体 Hiragino Sans GB 中易宋体 SimSun 文泉驿微米黑WenQuanYi Microhei
黑体-简(华文黑体)Heiti SC (STHeiti) 微软雅黑Microsoft YaHei
宋体-简(华文宋体)Songti SC (STSong)
iOS Android
黑体-简(华文黑体)Heiti SC (STHeiti) 思源黑体Noto Sans CJK SC
Droid Sans Fallback
无衬线 衬线 等宽
Lucida Grande Georgia Menlo
Helvetica Neue Times New Roman Courier
Arial

抛开宋/明体长时间作为系统默认字体,所产生的审美疲劳,宋/明体相比黑体是更合适作为内文字体. 大多的宋/明体针对内文设计,横细直粗,造型方正,笔画在小字号的情况下,不会糊在一起,给人一种素雅的感觉. 而黑体笔画粗壮有力,引人注目,更适合作为标题使用.

但大部分人已经习惯在网页上阅读黑体,以及宋/明体在字重过大的情况下,显示效果还是不太理想. 所以内文默认提供黑体,可选择性的切换宋/明体.

按照以上表格提供的中文字体,为此我为内文和标题编写两套 font-family. 关于这两套 font-family 的选择和排序,等空闲时,再写一篇文章谈下.

1
2
p { font-family: "Georgia", "Times New Roman", "Songti SC", "SimSun", serif; }
h1, h2, h3, h4, h5, h6 { font-family: "Lucida Grande", "Helvetica Neue", "Arial", "Hiragino Sans GB", "Noto Sans CJK SC", "Heiti SC", "Microsoft YaHei", "WenQuanYi Microhei", sans-serif;}

垂直的旋律

音阶

Robert Bringhurst 在《The Elements of Typographic Style》谈到字号大小之间的比例,形似于音乐中的音阶. 作曲时以某个特定的音阶为基础,才会形成特定的风格. 字号的排版同样如此,有规律的字号变化,才会形成特定的排版风格.

将内文以 16px 作为字号
标题 h1, h2, h3, h4, h5, h6 以 16px 作为字号基础,按同比例的递减

1
2
3
4
5
6
p  { font-size: 16px; }
h1 { font-size: 2em; }
h2 { font-size: 1.8em; }
h3 { font-size: 1.6em; }
h4 { font-size: 1.4em; }
h5, h6 { font-size: 1.2em; }

节拍

此外,Robert Bringhurst 还谈到版式中的空间就像音乐中的时间(Space in typography is like time in music),言下之意,把握间距(行高)就如把握节拍. 节拍是对时间的分割,倘若抢拍便失去节奏. 文字的间距(行高)亦是对空间的分割,不一致间距(行高)比例,便会失去「垂直的旋律」.

将内文以 1.7em 作为行高
标题 h1, h2, h3, h4, h5, h6 以 1.5em 作为行高.

1
2
p { line-height: 1.7em; }
h1, h2, h3, h4, h5, h6 { line-height: 1.5em; }

段首缩进 VS 段落间距

段落分隔对于中文排版而言也是特别重要,主要以「段首缩进」和「段落间距」两种方式表现,它们的唯一目的就是将段落分隔.

「段首缩进」主要用于印刷书籍,节省纵向空间,保持文本连贯,但一般在网页上的阅读速度较快,会使文字过于密集产生压力. 相反「段落间距」主要用于网页,充分利用网页无限的纵向空间,保障文本块的整洁,同时给予长篇阅读休息的间隙. 所以一般网页排版,会考虑选择「段落间距」,可以设置以下属性实现「段落间距」.

1
2
3
4
5
p { margin-bottom: 1.7em; }
h1, h2, h3, h4, h5, h6 {
margin-top: .7em;
margin-bottom: 0.2em;
}

对齐

汉字的方块性质构成了汉字独有的艺术美感,使其具有工整的特点,从而显现出中文排版的重要原则:所有元素都是正方体. 但从二十世纪开始使用标点后,以及中西文混排的情况越来越多,为了保证「禁则处理」和「齐头尾」实现,可能需要在不同条件下进行适当的断词处理.

「禁則」是来自日语的排版术语,主要指的就是禁止一些标点等字符出现在行首或行尾的规则,大致相当于汉语常说的「避头尾」.

可以设置以下属性实现「齐头尾」,其中inter-ideographic意思是「通过调整单词和字符之间的留白来实现两端对齐」.

1
2
3
4
p {
text-align: justify;
text-justify: inter-ideographic;
}

但这样的「齐头尾」并不是完美的,主要由于技术遗留原因,在 Windows 和 Linux 上的 webkit 浏览器并没有实现 inter-ideographic 导致中西文混排的时候,容易出现过度拉伸字间距的情况.

justify

左侧: inter-ideographic | 右侧: break-all

为此有一种不优雅的解决方案,在极易出现字间距拉伸的小尺寸屏幕(手机)上使用「断词处理」,避免字间距拉伸,可是这样也带来「无视避头尾规则」和「西文单词断词」的坏毛病. 这是用一种不优雅解决另一种不优雅,按需抉择吧.

可以设置以下属性进行「断词处理」

1
p { word-break: break-all; }

未作说明…

  • Kerning
  • 有序/无序列表
  • 「.」作为句号相比「。」的优势

参见:
Technical Web Typography: Guidelines and Techniques
Web Design is 95% Typography
The Elements of Typographic Style
Best Practices for Chinese Layout
JUSTFONT BLOG
Google
维基百科
知乎


制作 |

音乐 | hynuza

问题

Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id.

1
2
3
4
5
6
7
8
+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
| 3 | john@example.com |
+----+------------------+
Id is the primary key column for this table.

For example, after running your query, the above Person table should have the following rows:

1
2
3
4
5
6
+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
+----+------------------+

翻译

Person表中删除所有重复的邮箱,仅保留 id 最小的邮箱。

解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DELETE
FROM
Person
WHERE
id NOT IN (
SELECT
t.id
FROM
(
SELECT
`Email`,
min(id) AS id
FROM
Person
GROUP BY
`Email`
) t
)

问题

Given a list of non negative integers, arrange them such that they form the largest number.

For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

Note: The result may be very large, so you need to return a string instead of an integer.

翻译:

有一组非负整数,排列他们来获得一个最大的数。

例如,如果给了[3, 30, 34, 5, 9],那最大的数就是9534330

注意: 结果可能非常大,所以需要返回一个字符串(string)类型的数字而不是整型(integer)的。

问题

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

翻译

假设有一个n层的楼梯,每次你可以走1到2层。
有多少不同的方法可以走上去?

思路

第n层只可以从第n-1层走1层或者n-2层走2层到达。因此第n层的总方法数是第n-1层和n-2层之和。抽象后此问题成为了一个斐波那契数列问题。

代码

递归解法:

1
2
3
4
5
6
public static int climbStairs(long n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
return climbStairs(n - 1) + climbStairs(n - 2);
}

非递归解法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static int climbStairs(long n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
int all = 0, past = 2, pastTwo = 1;
int i = 3;
do{
all = past + pastTwo;
pastTwo = past;
past = all;
i++;
}while (i <= n);
return all;
}

遇到问题

最近一直有个问题困惑着我,apache、nodejs、tomcat不能同时在服务器80端口运行,对域名进行设置时使用ip:port又不能得到期望的结果(结果一直是以一个iframe的形式),因此就在segmentFault上发问:同一台服务器运行多个http服务如何实现?之后得到了数位大神的回答,大意就是采用反向代理来实现。因此百度了一些文章,也看了看apache的手册,大概解决了这个问题。

apache的思路

apache的思路应该是将服务和参数转发给真正的服务器,然后从服务器拿到结果返回给浏览器,思路和以前的模拟登录获取结果有点相似,不过这里apache都已经做好了,只需要配置好就可以了。

apache的域名和代理配置

首先是域名配置,还是和以前的vhosts配置一样

1
ServerName www.eg.com

我觉得要是做整个域名的转发这样就行了,接下来添加配置

1
2
3
4
5
ServerName www.eg.com
Order deny,allow
Allow from all
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

这样就将www.eg.com的请求转发到了8080端口。

我用nodejs启动了一个express应用,当然,只不过是输出了一句“hello world”。

clipboard.png

然后在浏览器中输入www.eg.com,就会顺利的出现“hello world”了。

其他事项

  • 需要开启apache代理的拓展

    1
    2
    3
    4
    LoadModule proxy modules/proxy.so
    LoadModule proxy_connect modules/proxy_connect.so
    LoadModule proxy_http modules/proxy_http.so
    LoadModule proxy_html modules/proxy_html.so
  • 需要设置hosts(windows下位置在c:/windows/system32/drivers/etc/hosts,linux下在/etc/hosts下)。

  • 经过我的测试,apache对apache自身的其他端口的代理和对nodejs的代理是正常工作的。

核心思想

Angular的核心思想是双向数据绑定依赖注入双向数据绑定使文档以数据驱动,而不是以DOM驱动;

I am here, Shanghai, the biggest city in China.

I am so so so little, I cannot make any changes for this city.

I come, then I leave, nothing would be left here, just like a life.

Quarrel is meaningless, this is the actual status which I live with.

Get up, work and sleep, day by day.

I have no aim, and I do not wanna improve myself.

I read news, glance over the bbses and play games, just like a mid-life man.

It’s sunny today, but I have no interest to go out to have a breath of fresh air.

Actually, I have keey away from outside for a long time.

Do I just wait to die to live the life ?  

Dobut.