干红干白不“自然”吗?
刚出地铁站,就被门口的葡萄酒店所吸引。进店后,才了解到卖的是最近时兴的自然酒。这瞬间勾起了我的兴趣,我真的还挺想尝一下自然酒是个啥滋味,一杯48元,真不算便宜。
颜色浅棕色,来自于白葡萄皮本身的色素,喝起来是淡淡的水果酸和涩感,感觉喝不出来风味描述中的“盐渍菠萝”味道,就是白葡萄酒的涩感,但还挺丝滑的,即使酒精度数12度也不会有强烈的酒精感。
借着买酒的机会,虚心跟老板娘请教学习何谓“自然酒”和“橙酒”。聊了一圈下来,发现这其实又是一种商家的噱头。
橙酒是不是白葡萄酒?
答案:是的,本质上就是白葡萄酒,只是因为品种+不去皮酿造,会把葡萄皮里的橙色色素带进酒里,看起来是橙色的,所以叫做橙酒。
传统的白葡萄酒跟自然酒的区别是啥?
答案:传统酿造法用的酵母是实验室培养出来的商业酵母,风味更加稳定。自然酒中的酵母来自于大自然,风味不稳定,有可能会把酒酿馊,产生多种风味。跟啤酒世界中的野菌啤酒的概念相同,都是酵母的一种来源。并不存在谁优谁劣的关系,只是一种平等关系下的不同类型。只是商家用各种故事包装,使其变得更加高大上,可以把酿馊的也拿来卖,美名其曰“限定款”。
橙酒是不是自然酒?
答案:自然酒只是酵母的来源,所以橙酒用传统商业酵母酿出来的就是传统橙酒,如果用的是自然酵母,就是自然橙酒。
于我而言,品酒知识学无止境呀。48元买到宝贵的行业知识还是挺值得的,但我肯定就不会花338去买一瓶名不见经转的小酒厂做出来的葡萄酒了,买瓶奔富389,会是更适合我的选择。
via 7gugu's Blog
看小红书上的自然酒笔记引发的思考立冬后的深圳居然还能回到30度,想着相机里还有2张拍立得没消耗完,所以去了海上世界取景。
刚出地铁站,就被门口的葡萄酒店所吸引。进店后,才了解到卖的是最近时兴的自然酒。这瞬间勾起了我的兴趣,我真的还挺想尝一下自然酒是个啥滋味,一杯48元,真不算便宜。
颜色浅棕色,来自于白葡萄皮本身的色素,喝起来是淡淡的水果酸和涩感,感觉喝不出来风味描述中的“盐渍菠萝”味道,就是白葡萄酒的涩感,但还挺丝滑的,即使酒精度数12度也不会有强烈的酒精感。
借着买酒的机会,虚心跟老板娘请教学习何谓“自然酒”和“橙酒”。聊了一圈下来,发现这其实又是一种商家的噱头。
橙酒是不是白葡萄酒?
答案:是的,本质上就是白葡萄酒,只是因为品种+不去皮酿造,会把葡萄皮里的橙色色素带进酒里,看起来是橙色的,所以叫做橙酒。
传统的白葡萄酒跟自然酒的区别是啥?
答案:传统酿造法用的酵母是实验室培养出来的商业酵母,风味更加稳定。自然酒中的酵母来自于大自然,风味不稳定,有可能会把酒酿馊,产生多种风味。跟啤酒世界中的野菌啤酒的概念相同,都是酵母的一种来源。并不存在谁优谁劣的关系,只是一种平等关系下的不同类型。只是商家用各种故事包装,使其变得更加高大上,可以把酿馊的也拿来卖,美名其曰“限定款”。
橙酒是不是自然酒?
答案:自然酒只是酵母的来源,所以橙酒用传统商业酵母酿出来的就是传统橙酒,如果用的是自然酵母,就是自然橙酒。
于我而言,品酒知识学无止境呀。48元买到宝贵的行业知识还是挺值得的,但我肯定就不会花338去买一瓶名不见经转的小酒厂做出来的葡萄酒了,买瓶奔富389,会是更适合我的选择。
via 7gugu's Blog
Git 3.0 即将问世:Git 用户需了解的下个重大版本信息
Git开发者正积极推进Git 3.0版本的开发工作,预计将于2026年底前发布。这将是自2014年Git 2.0发布以来首次重大版本升级。对于日常依赖Git的开发者而言,此次更新将带来影响版本控制底层机制的重大变革——您需要做好相应准备。
via TecHug (author: techug)
Git开发者正积极推进Git 3.0版本的开发工作,预计将于2026年底前发布。这将是自2014年Git 2.0发布以来首次重大版本升级。对于日常依赖Git的开发者而言,此次更新将带来影响版本控制底层机制的重大变革——您需要做好相应准备。
via TecHug (author: techug)
补牙-以及最近三两事
之前就发现自己门牙上旁边有个黑窟窿,可能是蛀牙什么的,上周有时间,就去最近的一个医院看了一下。看了之后发现蛀牙还真不少,总共6个小的,3个大的,反倒是门牙那个很显眼的,医生说不是蛀牙,是什么牙结石之类,后面做了牙周处理。
几个小的蛀牙用树脂填的,大的医生说最好用嵌体,总共花费了7-8千块钱,医保瞬间给我清空了属于是,自己还自费了6千。本来还觉得我的决定还是挺冲动的,没有货比三家去别的医院也看看,或许医生坑我呢,也许有更好的方案,现在觉得也没必要怀疑医生吧。
也是切身体会了电影《Eden》里的那个男主,为什么决定离开城市时候把自己牙全拔光了,牙医真的是现代社会不可或缺的职业呀。
补牙之前需要把蛀牙用那个类似小电钻的东西打磨掉,照片就不放了,看的吓人呢,几个小的牙齿没什么感觉,就是能闻到烧糊的味道,3个严重点的就感觉到一整酸痛的感觉,后面的医生拍的照片可以看出来,牙齿中间被打磨出了一个很深的十字形的坑,全程也是张了很久的嘴,感觉都快脱臼了。医生用3d扫描的设备,给牙齿做了个建模,这3个要做嵌体的,还要等厂家根据3D扫描生产出来才能做,医生说要等下周了,现在先临时用一个绿色的啥玩意填充了一下。
还是没想到自己蛀牙这么多,以为自己还是很年轻之类的,就一堆问题,可能是之前快乐水喝多了,医院也能听到一些10来岁的小孩,在那哭的特别大声,看来这玩意跟年纪也没什么关系,之后人生又要少了一个乐趣了。
之前也是刷到过一些做根管的视频,看着就很吓人,推荐各位没看过的去搜下看下,健全的还是要注意防护呀,看完就会瞬间有了敬畏之心了。医生也是一直有推荐用什么牙线清理,这玩意我到现在还是一次没用过,之前倒是有尝试,总感觉塞不到牙齿里面,后面还是要尝试一下。
----------------------
本来想着每周写一点什么的,这个打算是昨天写的,然后还约了个模特练习下拍照,也是因为是下雨,然后就是昨天早上睡了很久,大概是前天22:30就睡了,到第二天8:30,还是没睡醒,下午头昏脑涨,有点发烧的样子,中午的饭吃了两口也是吃不下了,有点想吐的。
没办法也是没出门,在家看了KT:T1的比赛,恭喜Faker的六冠王,这次比赛虽然国内没什么热度,赛事结束也是有点敷衍,但是我觉得5把都打满,也是蛮精彩的,尤其是第一把,不过后面KT感觉就一直不在状态,不知是不是因为英雄池太浅,反倒是T1越战越勇。
via 黑羽的个人博客
之前就发现自己门牙上旁边有个黑窟窿,可能是蛀牙什么的,上周有时间,就去最近的一个医院看了一下。看了之后发现蛀牙还真不少,总共6个小的,3个大的,反倒是门牙那个很显眼的,医生说不是蛀牙,是什么牙结石之类,后面做了牙周处理。
几个小的蛀牙用树脂填的,大的医生说最好用嵌体,总共花费了7-8千块钱,医保瞬间给我清空了属于是,自己还自费了6千。本来还觉得我的决定还是挺冲动的,没有货比三家去别的医院也看看,或许医生坑我呢,也许有更好的方案,现在觉得也没必要怀疑医生吧。
也是切身体会了电影《Eden》里的那个男主,为什么决定离开城市时候把自己牙全拔光了,牙医真的是现代社会不可或缺的职业呀。
补牙之前需要把蛀牙用那个类似小电钻的东西打磨掉,照片就不放了,看的吓人呢,几个小的牙齿没什么感觉,就是能闻到烧糊的味道,3个严重点的就感觉到一整酸痛的感觉,后面的医生拍的照片可以看出来,牙齿中间被打磨出了一个很深的十字形的坑,全程也是张了很久的嘴,感觉都快脱臼了。医生用3d扫描的设备,给牙齿做了个建模,这3个要做嵌体的,还要等厂家根据3D扫描生产出来才能做,医生说要等下周了,现在先临时用一个绿色的啥玩意填充了一下。
不过说到这个临时填充的,今天早上刷牙我尽然给它刷出来了,不知道吃饭东西会不会卡进这个牙坑里面,后来又用手塞了进去,感觉最近不能吃太刺激的了,毕竟那个坑也是离神经不远了。补完牙之后又是做的牙周,医生给打了一点镇静计,我也是全程没怎么看,只是感觉医生那什么塞进我的一个个牙缝,还有偶尔的酸痛,还有一阵阵烧糊的味道。结束之后看到我嘴里都是血,漱了漱口口后医生给上了个药,拿了漱口水,也是结束了。
还是没想到自己蛀牙这么多,以为自己还是很年轻之类的,就一堆问题,可能是之前快乐水喝多了,医院也能听到一些10来岁的小孩,在那哭的特别大声,看来这玩意跟年纪也没什么关系,之后人生又要少了一个乐趣了。
之前也是刷到过一些做根管的视频,看着就很吓人,推荐各位没看过的去搜下看下,健全的还是要注意防护呀,看完就会瞬间有了敬畏之心了。医生也是一直有推荐用什么牙线清理,这玩意我到现在还是一次没用过,之前倒是有尝试,总感觉塞不到牙齿里面,后面还是要尝试一下。
----------------------
本来想着每周写一点什么的,这个打算是昨天写的,然后还约了个模特练习下拍照,也是因为是下雨,然后就是昨天早上睡了很久,大概是前天22:30就睡了,到第二天8:30,还是没睡醒,下午头昏脑涨,有点发烧的样子,中午的饭吃了两口也是吃不下了,有点想吐的。
没办法也是没出门,在家看了KT:T1的比赛,恭喜Faker的六冠王,这次比赛虽然国内没什么热度,赛事结束也是有点敷衍,但是我觉得5把都打满,也是蛮精彩的,尤其是第一把,不过后面KT感觉就一直不在状态,不知是不是因为英雄池太浅,反倒是T1越战越勇。
via 黑羽的个人博客
若没有林纳斯·托瓦兹,Linux将如何延续
由托瓦兹及Linux内核核心领域维护者共同认可的开发者将接任领导职务。此人需获得广泛支持,因为任何人都可能随时基于现有Linux代码创建直接竞争项目。
via TecHug (author: techug)
由托瓦兹及Linux内核核心领域维护者共同认可的开发者将接任领导职务。此人需获得广泛支持,因为任何人都可能随时基于现有Linux代码创建直接竞争项目。
via TecHug (author: techug)
vue 生命周期
学习 vue 中一个非常重要的领域,就是生命周期,它包含了很多的内容。每个 vue 实例在被创建的时候都要经历一系列的初始化过程,这个过程就是 vue 的生命周期。 每个 vue 实例在被创建的时候都要经过一系列的初始化过程——例如,需要把设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等,我们要把这一系列的过程称为组件的`生命周期`(组件从注册到销毁的整个过程)。我们有时候需要在组件生命周期的某个过程中,执行某些代码,基于此,vue 提供了`生命周期钩子函数`,给了用户在不同阶段添加自己的代码的机会。 但是在此之前,我们要详细的介绍下组件的生命周期,以及生命后期中每个阶段组件完成和未完成的部分。 ## 一、组件的生命周期 放一张大家都很熟悉的官网文章中对生命周期的注释图。 从图中可以看出,vue 为生命周期提供了 8 个钩子函数,分别是: * beforeCreate: 创建前 * created: 创建后 * beforeMount: 挂载前 * mounted: 挂载后 * beforeUpate: 更新前 * upated: 更新后 * beforeDestoy: 销毁前 * destoyed: 销毁后 ### 1.beforeCreate beforeCreate 在 vue 实例发生之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 我们在上面的例子中在的 beforeCreate 钩子中调用 Vue 的 data 和 method,来看一下结果: 可以看到 Vue 中的 data 和方法都是去不到的,并且是在 wath 之前执行 ### 2.created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 **主要应用**:调用数据,调用方法,调用异步函数 console 输出的结果我们看一下 可以看到:created 钩子可以获取 Vue 的 data,调用 Vue 方法,获取原本 HTML 上的直接加载出来的 DOM,但是无法获取到通过挂载模板生成的 DOM(例如:v-for 循环遍历 Vue.list 生成 li) ### 3.beforeMount 在挂载开始之前被调用:相关的 render 函数(模板)首次被调用。 例如通过 v-for 生成的 html 还没有被挂载到页面上 ````js javascript beforeMount: function () { console.log('beforeMount:',document.getElementsByTagName('li').length); }, ```` console 打印出来的 beforeMount 为 1 ### 4.mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 **有初始值的 DOM 渲染,例如我们的初始数据 list,渲染出来的 li,只有这里才能获取** ````js javascript mounted: function () { console.log('mounted:',document.getElementsByTagName('li').length); }, ```` 结果 mounted: 3 , 可以看到到这里为止,挂载到实例上了,我们可以获取到 li 的个数了 ### 5.beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 当我们更改 Vue 的任何数据,都会触发该函数 ````js javascript beforeUpdate: "function () { console.log('beforeUpdate 钩子执行.'); console.log('beforeUpdate:'+this.message) }, ```` ### 6.updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 该钩子在服务器端渲染期间不被调用。 数据更新就会触发(vue 所有的数据只有有更新就会触发),如果想数据一遍就做统一的处理,可以用这个,如果想对不同数据的更新做不同的处理可以用 nextTick,或者是 watch 进行监听 ````js javascript updated: function () { console.log('updated 钩子执行...'); console.log('updated:',this.message) }, ```` ### 7.beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。 ### 8.destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。 **结果** 可以看打到销毁 Vue 实例时会调用这两个函数
via 子舒的博客
学习 vue 中一个非常重要的领域,就是生命周期,它包含了很多的内容。每个 vue 实例在被创建的时候都要经历一系列的初始化过程,这个过程就是 vue 的生命周期。 每个 vue 实例在被创建的时候都要经过一系列的初始化过程——例如,需要把设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等,我们要把这一系列的过程称为组件的`生命周期`(组件从注册到销毁的整个过程)。我们有时候需要在组件生命周期的某个过程中,执行某些代码,基于此,vue 提供了`生命周期钩子函数`,给了用户在不同阶段添加自己的代码的机会。 但是在此之前,我们要详细的介绍下组件的生命周期,以及生命后期中每个阶段组件完成和未完成的部分。 ## 一、组件的生命周期 放一张大家都很熟悉的官网文章中对生命周期的注释图。 从图中可以看出,vue 为生命周期提供了 8 个钩子函数,分别是: * beforeCreate: 创建前 * created: 创建后 * beforeMount: 挂载前 * mounted: 挂载后 * beforeUpate: 更新前 * upated: 更新后 * beforeDestoy: 销毁前 * destoyed: 销毁后 ### 1.beforeCreate beforeCreate 在 vue 实例发生之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 我们在上面的例子中在的 beforeCreate 钩子中调用 Vue 的 data 和 method,来看一下结果: 可以看到 Vue 中的 data 和方法都是去不到的,并且是在 wath 之前执行 ### 2.created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 **主要应用**:调用数据,调用方法,调用异步函数 console 输出的结果我们看一下 可以看到:created 钩子可以获取 Vue 的 data,调用 Vue 方法,获取原本 HTML 上的直接加载出来的 DOM,但是无法获取到通过挂载模板生成的 DOM(例如:v-for 循环遍历 Vue.list 生成 li) ### 3.beforeMount 在挂载开始之前被调用:相关的 render 函数(模板)首次被调用。 例如通过 v-for 生成的 html 还没有被挂载到页面上 ````js javascript beforeMount: function () { console.log('beforeMount:',document.getElementsByTagName('li').length); }, ```` console 打印出来的 beforeMount 为 1 ### 4.mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 **有初始值的 DOM 渲染,例如我们的初始数据 list,渲染出来的 li,只有这里才能获取** ````js javascript mounted: function () { console.log('mounted:',document.getElementsByTagName('li').length); }, ```` 结果 mounted: 3 , 可以看到到这里为止,挂载到实例上了,我们可以获取到 li 的个数了 ### 5.beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 当我们更改 Vue 的任何数据,都会触发该函数 ````js javascript beforeUpdate: "function () { console.log('beforeUpdate 钩子执行.'); console.log('beforeUpdate:'+this.message) }, ```` ### 6.updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 该钩子在服务器端渲染期间不被调用。 数据更新就会触发(vue 所有的数据只有有更新就会触发),如果想数据一遍就做统一的处理,可以用这个,如果想对不同数据的更新做不同的处理可以用 nextTick,或者是 watch 进行监听 ````js javascript updated: function () { console.log('updated 钩子执行...'); console.log('updated:',this.message) }, ```` ### 7.beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。 ### 8.destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。 **结果** 可以看打到销毁 Vue 实例时会调用这两个函数
via 子舒的博客
文字溢出隐藏以及和 flex 冲突的问题
在某些段落中,页面要求文字只显示一行,但是`width`固定,而文字过长,就会出现一个需求,超过长度限制的文字被隐藏且显示省略号,css 支持这样的属性。 **单行文本溢出隐藏** ````css div{ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } ```` **多行文本溢出隐藏** ```css div { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } ``` 简单的几行代码就可以达到我们的要求。 **但是有一个我们需要注意的地方!!** flex 布局是前端写代码经常使用的一种布局方式,简单便捷且有效,但是在使用 flex 布局的元素中不能同时使用文字溢出隐藏,也就是两者不能同时出现在同一标签中。 这里,我们也有对应的解决办法。 只要保证 flex 布局和隐藏的样式不在同级元素中就可以,所以在文字外部多包裹一层标签。 可以采用下面这段代码的写法; ````html
````
via 子舒的博客
在某些段落中,页面要求文字只显示一行,但是`width`固定,而文字过长,就会出现一个需求,超过长度限制的文字被隐藏且显示省略号,css 支持这样的属性。 **单行文本溢出隐藏** ````css div{ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } ```` **多行文本溢出隐藏** ```css div { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } ``` 简单的几行代码就可以达到我们的要求。 **但是有一个我们需要注意的地方!!** flex 布局是前端写代码经常使用的一种布局方式,简单便捷且有效,但是在使用 flex 布局的元素中不能同时使用文字溢出隐藏,也就是两者不能同时出现在同一标签中。 这里,我们也有对应的解决办法。 只要保证 flex 布局和隐藏的样式不在同级元素中就可以,所以在文字外部多包裹一层标签。 可以采用下面这段代码的写法; ````html
````
via 子舒的博客
推荐书籍《CSS 世界》
本书从前端开发人员的需求出发,以“流”为线索,从结构、内容到美化装饰灯方面,全面且深入地讲解前端开发人员必须了解和掌握的大量的 CSS 知识点。同时,作者结合多年的从业经验,通过大量的实战案例,详尽解析 CSS 的相关知识与常见问题。 作者还为本书开发了专门的配套网站,进行实例展示。问题答疑。作为一本 CSS 深度学习的书,书中介绍大量许多前端开发人员都不知道的 CSS 知识点。通过阅读本书,读者会对 CSS 世界的深度和广度有一个全新的认识。 这本书作者采用口语化的方式,讲述在 css 中遇到的一些有意思的问题,循序渐进,引人入胜,对有前端基础的人来说,读这本书还是很有意思的。我经常在闲余时间看看这本书,会给我一些启发。
via 子舒的博客
本书从前端开发人员的需求出发,以“流”为线索,从结构、内容到美化装饰灯方面,全面且深入地讲解前端开发人员必须了解和掌握的大量的 CSS 知识点。同时,作者结合多年的从业经验,通过大量的实战案例,详尽解析 CSS 的相关知识与常见问题。 作者还为本书开发了专门的配套网站,进行实例展示。问题答疑。作为一本 CSS 深度学习的书,书中介绍大量许多前端开发人员都不知道的 CSS 知识点。通过阅读本书,读者会对 CSS 世界的深度和广度有一个全新的认识。 这本书作者采用口语化的方式,讲述在 css 中遇到的一些有意思的问题,循序渐进,引人入胜,对有前端基础的人来说,读这本书还是很有意思的。我经常在闲余时间看看这本书,会给我一些启发。
via 子舒的博客
Chrome 浏览器中对 autoplay 的一些处理技巧
我在写博客的时候,想给博客网页添加自己喜欢的音乐,这样我在写作和阅读的时候,心情也会比较愉悦,这个时候,我们就需要用到`audio`这个标签。 ````html ```` 同时 audio 标签还带有很多实用的属性,常用的有以下几个: * src -- 这个就不说了,懂的都懂 * autoplay -- 如果出现该属性,音频在就绪后马上播放 * controls -- 网页中显示音频控件 * loop -- 循环播放 * muted -- 默认静音 但是我在设置 autoplay 的时候发现,Chrome 对自动播放深恶痛绝,直接从根源上限制了这个属性的开启,意思是说,这个属性直接禁用,在打开网页没有交互的情况下,不允许自动播放。 但仔细想一想,这个做法其实是对用户比较有利的。假设用户使用的时候宽带流量,直接自动播放视频、音频,就会对用户造成损失。甚至一些广告会自动播放,这就直接影响到了用户的体验。所以,对于 Chrome 的做法我还是比较赞同的。 回过头一想,不对啊,我的目的是解决这个问题,不是夸赞谷歌的。我想给自己的个人博客添加喜欢的音乐,所以我找了一个不算办法的办法。我直接在模拟一个事件,当鼠标点击网页任意处的时候,自动触发 autoplay 的音频效果,直接上代码。 ````html ```` 这样处理过之后,插入音频,任意点击网页某个地方,都会触发播放效果,但凡事有利有弊,这样做的话,一旦开启播放,将无法启用暂停功能,也就是说会一直播放下去 如果是像我这样写个人博客,这个弊端倒是影响不大,我在这里记录一下这个方法。
via 子舒的博客
我在写博客的时候,想给博客网页添加自己喜欢的音乐,这样我在写作和阅读的时候,心情也会比较愉悦,这个时候,我们就需要用到`audio`这个标签。 ````html ```` 同时 audio 标签还带有很多实用的属性,常用的有以下几个: * src -- 这个就不说了,懂的都懂 * autoplay -- 如果出现该属性,音频在就绪后马上播放 * controls -- 网页中显示音频控件 * loop -- 循环播放 * muted -- 默认静音 但是我在设置 autoplay 的时候发现,Chrome 对自动播放深恶痛绝,直接从根源上限制了这个属性的开启,意思是说,这个属性直接禁用,在打开网页没有交互的情况下,不允许自动播放。 但仔细想一想,这个做法其实是对用户比较有利的。假设用户使用的时候宽带流量,直接自动播放视频、音频,就会对用户造成损失。甚至一些广告会自动播放,这就直接影响到了用户的体验。所以,对于 Chrome 的做法我还是比较赞同的。 回过头一想,不对啊,我的目的是解决这个问题,不是夸赞谷歌的。我想给自己的个人博客添加喜欢的音乐,所以我找了一个不算办法的办法。我直接在模拟一个事件,当鼠标点击网页任意处的时候,自动触发 autoplay 的音频效果,直接上代码。 ````html ```` 这样处理过之后,插入音频,任意点击网页某个地方,都会触发播放效果,但凡事有利有弊,这样做的话,一旦开启播放,将无法启用暂停功能,也就是说会一直播放下去 如果是像我这样写个人博客,这个弊端倒是影响不大,我在这里记录一下这个方法。
via 子舒的博客
对全栈的一些思考
这里我要推荐一本书,叫做《Web 全栈工程师的自我修养》,在看的过程中,自己也代入进去进行分析,然后写了这篇笔记。 “全栈工程师正在成为 IT 行业的新秀,无论是在上市互联网公司还是在创业公司,都对全栈工程师青睐有加。本书作者是腾讯公 司高级工程师,在前端、后端和 APP 开发方面都有丰富的经验,在本书中分享了全栈工程师的技能与要求、核心竞争力、未来发 展方向、对移动端的思考。除此之外,本书还详细记录了作者从零开始、学习心得。本书内容全面、客观务实适合互联网行业新人、程序员。以及期待技术转型的从业者阅读参考。” 作者余果毕业于西安点击科技大学软件工程学院,曾任腾讯社交用户体验设计部高级 UI 工程师、前端开发负责人,负责多个项目的产品设计,以自身的经历为模板撰写了这本书。 从自身说起,因为对技术和机器的热爱让他走向了计算机这门行业,而在书中,他也经常提及自己理性和感性思维相结合,对全栈工程师进行了深入分析。 全栈工程师是指一个能够处理数据库、服务器、系统工程和客户端所有工作的工程师。根据项目的不同,客户需要的可能是移动栈、Web 栈,或者原生应用程序栈。这是官方的定义。而以我目前出入前端的思维通俗点来说,大概也就是一个人包揽前端,后端,一个人处理数据进行项目维护,甚至于设计图都是自己做的。 很多人都说全栈有很多好处,不同担心很多人编写不同步,思维不一致,导致做出来的项目每个人的想法不同,全栈一个人包揽所有的过程,都在自己脑子里。 可能因为我进入这个行业不久,我认为全栈是不太合理的存在,打个比方说,在流水线还没出现之间,手工作坊基本都是一个人负责所有的产品制作,从原料,制作,打磨,成品,或许很经过很多步骤,但是一个人都可以完美的做出来,就这样类似全栈工程师这样的存在。 而生产线就更像一个团队,产品,UI,前端,后端测试等,每个人相互配合。 全栈和团队比起来,我个人觉得团队的优势更大,但架不住老板喜欢一个人干三个人活,更喜欢全栈一点。 培养一个全栈的花费的时间和精力难以想象,甚至不确定培养一定成功,但是如果专精某一技术领域,成为高级工程师的概率绝对远大于一个全栈。当然这也只是我个人的臆测,并没有具体的数据支撑。 书中也提及,流水线带来的另一个好处,不会对某个工程师产生依赖性,即使失去这个员工,也可以让被人接手工作 说了很多团队化的好处,这不代表就没有弊端,肯定是有的,书中总结出来几点: * 工程师职责不清导致效率低 * 工程师缺乏主人感导致产品质量差 * 工程师缺乏全局的视野影响个人成长 * 更多角色导致项目效率低下 “因为各司其职的工作流程有效率低下、成本高的缺点,所以很多创业公司都不会配备齐全的流水线,而是希望采用更灵活的方式来组建团队,全栈工程师也因此成为了理想的选择。但是全栈工程师的兴起还离不开这两个重要因素:技术的发展,以及提供 PaaS 服务的平台越来越多。” 虽然做成为一个全栈工程师需要耗费大量的时间精力来打磨,但是这个思维我还是比较喜欢的。比如说,有 a,b,c 三个人,分别擅长各自的领域,有一天他们共同负责的项目出了一个小问题,但是问题出在哪里领域还不知道,虽然是个小问题,但需要每个人去查验一遍,因为是三个领域,这就导致应该有两个人的查验是无效的,这从另一个方向来说也降低了项目效率。 然后这时候,有一个工程师 s,注意他不是全栈工程师,只是喜欢学习多领域的技术,掌握了一些不算太高深的技术知识,查验了一遍,很快就找出了问题所在。 那他一个人效率就相当于三个的效率了,其实这样说并不严谨,我也只是打个比方。 我突然想到一句话,不知道说的准确与否, “全栈的职位存在是不合理的,但全栈的思维是一个有上进心的工程师所必备的。”
via 子舒的博客
这里我要推荐一本书,叫做《Web 全栈工程师的自我修养》,在看的过程中,自己也代入进去进行分析,然后写了这篇笔记。 “全栈工程师正在成为 IT 行业的新秀,无论是在上市互联网公司还是在创业公司,都对全栈工程师青睐有加。本书作者是腾讯公 司高级工程师,在前端、后端和 APP 开发方面都有丰富的经验,在本书中分享了全栈工程师的技能与要求、核心竞争力、未来发 展方向、对移动端的思考。除此之外,本书还详细记录了作者从零开始、学习心得。本书内容全面、客观务实适合互联网行业新人、程序员。以及期待技术转型的从业者阅读参考。” 作者余果毕业于西安点击科技大学软件工程学院,曾任腾讯社交用户体验设计部高级 UI 工程师、前端开发负责人,负责多个项目的产品设计,以自身的经历为模板撰写了这本书。 从自身说起,因为对技术和机器的热爱让他走向了计算机这门行业,而在书中,他也经常提及自己理性和感性思维相结合,对全栈工程师进行了深入分析。 全栈工程师是指一个能够处理数据库、服务器、系统工程和客户端所有工作的工程师。根据项目的不同,客户需要的可能是移动栈、Web 栈,或者原生应用程序栈。这是官方的定义。而以我目前出入前端的思维通俗点来说,大概也就是一个人包揽前端,后端,一个人处理数据进行项目维护,甚至于设计图都是自己做的。 很多人都说全栈有很多好处,不同担心很多人编写不同步,思维不一致,导致做出来的项目每个人的想法不同,全栈一个人包揽所有的过程,都在自己脑子里。 可能因为我进入这个行业不久,我认为全栈是不太合理的存在,打个比方说,在流水线还没出现之间,手工作坊基本都是一个人负责所有的产品制作,从原料,制作,打磨,成品,或许很经过很多步骤,但是一个人都可以完美的做出来,就这样类似全栈工程师这样的存在。 而生产线就更像一个团队,产品,UI,前端,后端测试等,每个人相互配合。 全栈和团队比起来,我个人觉得团队的优势更大,但架不住老板喜欢一个人干三个人活,更喜欢全栈一点。 培养一个全栈的花费的时间和精力难以想象,甚至不确定培养一定成功,但是如果专精某一技术领域,成为高级工程师的概率绝对远大于一个全栈。当然这也只是我个人的臆测,并没有具体的数据支撑。 书中也提及,流水线带来的另一个好处,不会对某个工程师产生依赖性,即使失去这个员工,也可以让被人接手工作 说了很多团队化的好处,这不代表就没有弊端,肯定是有的,书中总结出来几点: * 工程师职责不清导致效率低 * 工程师缺乏主人感导致产品质量差 * 工程师缺乏全局的视野影响个人成长 * 更多角色导致项目效率低下 “因为各司其职的工作流程有效率低下、成本高的缺点,所以很多创业公司都不会配备齐全的流水线,而是希望采用更灵活的方式来组建团队,全栈工程师也因此成为了理想的选择。但是全栈工程师的兴起还离不开这两个重要因素:技术的发展,以及提供 PaaS 服务的平台越来越多。” 虽然做成为一个全栈工程师需要耗费大量的时间精力来打磨,但是这个思维我还是比较喜欢的。比如说,有 a,b,c 三个人,分别擅长各自的领域,有一天他们共同负责的项目出了一个小问题,但是问题出在哪里领域还不知道,虽然是个小问题,但需要每个人去查验一遍,因为是三个领域,这就导致应该有两个人的查验是无效的,这从另一个方向来说也降低了项目效率。 然后这时候,有一个工程师 s,注意他不是全栈工程师,只是喜欢学习多领域的技术,掌握了一些不算太高深的技术知识,查验了一遍,很快就找出了问题所在。 那他一个人效率就相当于三个的效率了,其实这样说并不严谨,我也只是打个比方。 我突然想到一句话,不知道说的准确与否, “全栈的职位存在是不合理的,但全栈的思维是一个有上进心的工程师所必备的。”
via 子舒的博客
HTML 事件属性--DOM
研究 html 的`对象,事件和方法`,从 js 的角度来思考,这个标签的属性是通过什么方法,触发什么事件来实现的 1. 键盘鼠标事件 2. 页面窗口事件 3. 表单事件 ## 一、window 事件属性 针对 window 对象触发的事件,在`
`中执行 ### 1.onbeforeprint/onafterprint 在浏览器打印之间/后触发 ````html ```` 打印前和打印后的事件方法类似,一个是在打印前触发事件,一个是在打印这个事件结束之后触发`onafterprint`这个事件 ### 2.onbeforeunload/unload 离开页面之间触发的事件/之后触发的事件 打开 f12,然后刷新,或者关闭浏览器,可以在浏览器触发事件 ````html ```` ### 3.onerror 当图片出错是可以触发该事件,支持该事件的标签只有 ``,``,`
测试
```` 每次滚动时都可以触发,可以绑定到 body 上 ### 9.onscroll 当元素滚动条被滚动时触发的事件 ````html
In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
滑动了次
```` 这个案例---滑动滚动计数 >区别:
1.`wheel`在滚轮滑动的时候有效,鼠标拖拽的时候无效
2.`onscroll`不管在滑动还是拖动的时候,均生效
via 子舒的博客
研究 html 的`对象,事件和方法`,从 js 的角度来思考,这个标签的属性是通过什么方法,触发什么事件来实现的 1. 键盘鼠标事件 2. 页面窗口事件 3. 表单事件 ## 一、window 事件属性 针对 window 对象触发的事件,在`
`中执行 ### 1.onbeforeprint/onafterprint 在浏览器打印之间/后触发 ````html ```` 打印前和打印后的事件方法类似,一个是在打印前触发事件,一个是在打印这个事件结束之后触发`onafterprint`这个事件 ### 2.onbeforeunload/unload 离开页面之间触发的事件/之后触发的事件 打开 f12,然后刷新,或者关闭浏览器,可以在浏览器触发事件 ````html ```` ### 3.onerror 当图片出错是可以触发该事件,支持该事件的标签只有 ``,``,`
测试
```` 每次滚动时都可以触发,可以绑定到 body 上 ### 9.onscroll 当元素滚动条被滚动时触发的事件 ````html
In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
滑动了次
```` 这个案例---滑动滚动计数 >区别:
1.`wheel`在滚轮滑动的时候有效,鼠标拖拽的时候无效
2.`onscroll`不管在滑动还是拖动的时候,均生效
via 子舒的博客
小张厨房日记(更新中...)
厨房日记,记录我的'高光'时刻 今日菜谱 ### 莴笋炒肉 准备食材:两根莴笋,一块猪肉,两只青椒 调料:盐,酱油,醋,油,料酒,姜,蒜 1. 炒菜前 10 分钟将猪肉从冰箱取出,放进碗中,用水浸解冻 2. 将莴笋削皮洗净,用刀切成片状 3. 将浸泡解冻好的猪肉取出,切成肉丁 4. 切少许姜和蒜 5. 准备好两根干辣椒 6. 往锅中倒入一勺油,待至烧熟后,将姜和蒜倒入翻炒 7. 将猪肉倒入锅中大火爆炒,并倒入少许料酒和酱油 8. 一到两分钟过后,将莴笋倒入锅中,并添至少许清水防止太干 9. 翻炒时倒入少许醋,盐,并放入干辣椒, 10. 翻炒防止糊锅,静置等待菜熟 没有很复杂的过程,只是细心就可以做出让自己感受舒心的菜 --- **(更新 2020.11.10)** ### 萝卜炖牛肉 准备食材:一根萝卜,四根胡萝卜,一大块牛肉,一卷粉丝 调料:盐,酱油,醋,油,料酒,姜,蒜,胡椒,八角 1. 将牛肉从冰箱取出,切成两块,取一碗清水,然后放在水中化冻 2. 牛肉解冻十分钟左右取出,均匀切碎,根据自己口感可随意 3. 切半块姜,半个蒜,起锅烧油,下葱姜蒜, >暂时没有小葱,等下次有了在下 4. 加入三四片干辣椒,少许胡椒,八角, 5. 等到锅中调料榨出香味,下牛肉,翻炒均匀防止糊锅 6. 倒入料酒,酱油 7. 在翻炒的过程中,用炖锅烧半锅清水,2-3 分钟后,将烧锅内牛肉、配料全部倒入炖锅,用勺子翻滚均匀 8. 用盖子盖住 9. 将萝卜切成片,稍微有点厚度的那种,不薄也不厚,6-7 分钟左右,下萝卜,并加入适当的盐 10. 下稍加翻滚,盖住盖子,留一个缝隙 11. 在这个期间洗净胡萝卜,去皮,切成块,等到烧锅 20 分钟左右,下胡萝卜和粉丝 >为什么要这么晚才下胡萝卜和粉丝呢? >因为他俩比较软,熟得快,如果放在锅中时间过长,很容易煮烂 12. 继续煮至 30 分钟左右,煮的差不多了,尝一下咸淡,可适当加入调料 13. 放一会就可以出锅啦 这是一道耗时比较长的菜,可以慢慢做,大致是这些流程,具体的可根据实际情况调整,比如加入的配菜不同 ---
via 子舒的博客
厨房日记,记录我的'高光'时刻 今日菜谱 ### 莴笋炒肉 准备食材:两根莴笋,一块猪肉,两只青椒 调料:盐,酱油,醋,油,料酒,姜,蒜 1. 炒菜前 10 分钟将猪肉从冰箱取出,放进碗中,用水浸解冻 2. 将莴笋削皮洗净,用刀切成片状 3. 将浸泡解冻好的猪肉取出,切成肉丁 4. 切少许姜和蒜 5. 准备好两根干辣椒 6. 往锅中倒入一勺油,待至烧熟后,将姜和蒜倒入翻炒 7. 将猪肉倒入锅中大火爆炒,并倒入少许料酒和酱油 8. 一到两分钟过后,将莴笋倒入锅中,并添至少许清水防止太干 9. 翻炒时倒入少许醋,盐,并放入干辣椒, 10. 翻炒防止糊锅,静置等待菜熟 没有很复杂的过程,只是细心就可以做出让自己感受舒心的菜 --- **(更新 2020.11.10)** ### 萝卜炖牛肉 准备食材:一根萝卜,四根胡萝卜,一大块牛肉,一卷粉丝 调料:盐,酱油,醋,油,料酒,姜,蒜,胡椒,八角 1. 将牛肉从冰箱取出,切成两块,取一碗清水,然后放在水中化冻 2. 牛肉解冻十分钟左右取出,均匀切碎,根据自己口感可随意 3. 切半块姜,半个蒜,起锅烧油,下葱姜蒜, >暂时没有小葱,等下次有了在下 4. 加入三四片干辣椒,少许胡椒,八角, 5. 等到锅中调料榨出香味,下牛肉,翻炒均匀防止糊锅 6. 倒入料酒,酱油 7. 在翻炒的过程中,用炖锅烧半锅清水,2-3 分钟后,将烧锅内牛肉、配料全部倒入炖锅,用勺子翻滚均匀 8. 用盖子盖住 9. 将萝卜切成片,稍微有点厚度的那种,不薄也不厚,6-7 分钟左右,下萝卜,并加入适当的盐 10. 下稍加翻滚,盖住盖子,留一个缝隙 11. 在这个期间洗净胡萝卜,去皮,切成块,等到烧锅 20 分钟左右,下胡萝卜和粉丝 >为什么要这么晚才下胡萝卜和粉丝呢? >因为他俩比较软,熟得快,如果放在锅中时间过长,很容易煮烂 12. 继续煮至 30 分钟左右,煮的差不多了,尝一下咸淡,可适当加入调料 13. 放一会就可以出锅啦 这是一道耗时比较长的菜,可以慢慢做,大致是这些流程,具体的可根据实际情况调整,比如加入的配菜不同 ---
via 子舒的博客
为什么 getTime() 返回 1970 年至今的毫秒?
今天在写 new Date() 时候,无意中发现了一个很有意思的方法,`getTime()`,百度了一下,有人说是计算从 1970 年 1 月 1 日至今的毫秒数 >为什么要是 1970 年呢? ````js new Date().getTime(); // xxxxxxxxxxx ```` 这个起源于 unix 的诞生,因为 Unix 在 1969 年被开发出来,1971 年正式发布,在这之前没有机器会需要来表示 1970-01-01-00:00:00 之前的时间,后面的语言很多就沿用了这一习惯,js 只是也沿用了这种习惯而已。 当然,这一做法现在看来是很有问题的,例如不方便用它表示更早的时间而且精度有限。 定义 time 从 1970 年 1 月 1 日开始,忽然想到在 JAVA 里,Oracle 数据库时间也是从 1970 年 1 月 1 日开始计算。 比如 java 类代码: ````java Date date = new Date(0); System.out.println(date); // 打印出来的结果:Thu Jan 01 08:00:00 CST 1970也 ```` 是 1970 年 1 月 1 日,实际上时分秒是 0 点 0 分 0 秒 (这里打印出来是 8 点,稍后会作解释)。 为什么这个时间会定义在 1970 年 1 月 1 日这个时候呢? 于是开始了 Google,中文网页根本找不到答案。于是试着搜索英文关键字,在 Sun java 论坛总算找到准确的帖子: http://forums.sun.com/thread.jspa?threadID=595140&start=15 其中有一个回复: I suspect that Java was born and raised on a UNIX system. UNIX considers the epoch (when did time begin) to be midnight, January 1, 1970. 是说 java 起源于 UNIX 系统,而 UNIX 认为 1970 年 1 月 1 日 0 点是时间纪元。 但这依然没很好的解释"为什么",出于好奇,继续 Google,总算找到了答案: http://en.wikipedia.org/wiki/Unix_time 这里的解释是: 最初计算机操作系统是 32 位,而时间也是用 32 位表示。 System.out.println(Integer.MAX_VALUE); 2147483647 Integer 在 JAVA 内用 32 位表示,因此 32 位能表示的最大值是 2147483647。另外 1 年 365 天的总秒数是 31536000,2147483647/31536000 = 68.1,也就是说 32 位能表示的最长时间是 68 年,而实际上到 2038 年 01 月 19 日 03 时 14 分 07 秒,便会到达最大时间,过了这个时间点,所有 32 位操作系统时间便会变为 10000000 00000000 00000000 00000000 也就是 1901 年 12 月 13 日 20 时 45 分 52 秒,这样便会出现时间回归的现象,很多软件便会运行异常了。 到这里,我想问题的答案已经出来了: 因为用 32 位来表示时间的最大间隔是 68 年,而最早出现的 UNIX 操作系统考虑到计算机产生的年代和应用的时限综合取了 1970 年 1 月 1 日作为 UNIX TIME 的纪元时间 (开始时间),而 java 自然也遵循了这一约束。 至于时间回归的现象相信随着 64 为操作系统的产生逐渐得到解决,因为用 64 位操作系统可以表示到 292,277,026,596 年 12 月 4 日 15 时 30 分 08 秒,相信我们的 N 代子孙,哪怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后了。 最后一个问题: 上面 System.out.println(new Date(0)),打印出来的时间是 8 点而非 0 点,原因是存在系统时间和本地时间的问题,其实系统时间依然是 0 点,只不过我的电脑时区设置为东 8 区,故打印的结果是 8 点。
via 子舒的博客
今天在写 new Date() 时候,无意中发现了一个很有意思的方法,`getTime()`,百度了一下,有人说是计算从 1970 年 1 月 1 日至今的毫秒数 >为什么要是 1970 年呢? ````js new Date().getTime(); // xxxxxxxxxxx ```` 这个起源于 unix 的诞生,因为 Unix 在 1969 年被开发出来,1971 年正式发布,在这之前没有机器会需要来表示 1970-01-01-00:00:00 之前的时间,后面的语言很多就沿用了这一习惯,js 只是也沿用了这种习惯而已。 当然,这一做法现在看来是很有问题的,例如不方便用它表示更早的时间而且精度有限。 定义 time 从 1970 年 1 月 1 日开始,忽然想到在 JAVA 里,Oracle 数据库时间也是从 1970 年 1 月 1 日开始计算。 比如 java 类代码: ````java Date date = new Date(0); System.out.println(date); // 打印出来的结果:Thu Jan 01 08:00:00 CST 1970也 ```` 是 1970 年 1 月 1 日,实际上时分秒是 0 点 0 分 0 秒 (这里打印出来是 8 点,稍后会作解释)。 为什么这个时间会定义在 1970 年 1 月 1 日这个时候呢? 于是开始了 Google,中文网页根本找不到答案。于是试着搜索英文关键字,在 Sun java 论坛总算找到准确的帖子: http://forums.sun.com/thread.jspa?threadID=595140&start=15 其中有一个回复: I suspect that Java was born and raised on a UNIX system. UNIX considers the epoch (when did time begin) to be midnight, January 1, 1970. 是说 java 起源于 UNIX 系统,而 UNIX 认为 1970 年 1 月 1 日 0 点是时间纪元。 但这依然没很好的解释"为什么",出于好奇,继续 Google,总算找到了答案: http://en.wikipedia.org/wiki/Unix_time 这里的解释是: 最初计算机操作系统是 32 位,而时间也是用 32 位表示。 System.out.println(Integer.MAX_VALUE); 2147483647 Integer 在 JAVA 内用 32 位表示,因此 32 位能表示的最大值是 2147483647。另外 1 年 365 天的总秒数是 31536000,2147483647/31536000 = 68.1,也就是说 32 位能表示的最长时间是 68 年,而实际上到 2038 年 01 月 19 日 03 时 14 分 07 秒,便会到达最大时间,过了这个时间点,所有 32 位操作系统时间便会变为 10000000 00000000 00000000 00000000 也就是 1901 年 12 月 13 日 20 时 45 分 52 秒,这样便会出现时间回归的现象,很多软件便会运行异常了。 到这里,我想问题的答案已经出来了: 因为用 32 位来表示时间的最大间隔是 68 年,而最早出现的 UNIX 操作系统考虑到计算机产生的年代和应用的时限综合取了 1970 年 1 月 1 日作为 UNIX TIME 的纪元时间 (开始时间),而 java 自然也遵循了这一约束。 至于时间回归的现象相信随着 64 为操作系统的产生逐渐得到解决,因为用 64 位操作系统可以表示到 292,277,026,596 年 12 月 4 日 15 时 30 分 08 秒,相信我们的 N 代子孙,哪怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后了。 最后一个问题: 上面 System.out.println(new Date(0)),打印出来的时间是 8 点而非 0 点,原因是存在系统时间和本地时间的问题,其实系统时间依然是 0 点,只不过我的电脑时区设置为东 8 区,故打印的结果是 8 点。
via 子舒的博客