版权所有,未经许可不得转载, 据悉,下载量仅统计App Store和Google Play,不包括中国及其它地区第三方安卓市场。,
2022年1月全球热门移动应用下载TOP10, Sensor Tower信息显示,2022年1月抖音及其海外版TikTok以将近6700万的下载量,成为全球移动应用(非游戏)下载榜冠军,和2021年1月相比增长7.1%。其中,抖音的下载量占14.7%,TikTok美国市场的下载量占比为10.7%。, 【手机中国新闻】应用是智能手机上必不可少的一个元素,我们每天都在各种应用之间穿梭,获取和分享海量的信息。那么,你知道目前全球最受欢迎的应用都有哪些吗?日前,Sensor Tower商店情报发布最新数据,抖音和它的海外版TikTok表现相当亮眼!
版权所有,未经许可不得转载, 3、每周排位赛海克斯能量上限翻倍,同时增加获取量。官方想为努力冲击更高段位的玩家提供更多的晋升机会,海克斯能量的周上限翻倍,同时增加积极比赛、对局表现和出类拔萃的玩家的海克斯能量获取量。, 1、优化钻石以上玩家上分体验。官方希望让段位攀升过程中的体验变得更加平滑,同时为玩家的对局提供更多队友和对手。因此,本次更新后,部分钻石、大师、宗师和王者段位的玩家,在对局胜利之后将获得更多的胜点,在对局失败之后也将扣除更少的胜点。, 具体更新内容如下:, 【CNMO新闻】2月24日早上,英雄联盟手游官博宣布:为了带给大家更好的游戏体验,我们于2月24日9:00—12:00进行不停机更新。本次更新,我们再次对排位匹配体验进行了部分优化,以便召唤师们能更好的进行游戏,享受游戏乐趣。本次iOS平台更新大小为21.03M,安卓为20.05M。
截至目前,支付宝、微信支付均与云闪付App逐步打通条码支付环节。现在,微信支付与云闪付App已经实现线下条码互认互扫。那么,未来支付宝和微信支付会不会也往这一步走呢?, 除了与云闪付进行合作,微信支付与阿里旗下的应用也变得愈加紧密。前不久,阿里旗下饿了么、优酷等应用均已接入微信支付。此外,闲鱼、盒马等App也已申请接入微信支付,正在等待微信审核。, 此前,微信支付和银联云闪付共同推进财付通、银联与建行、中行、交行、平安、中信等多家银行的合作,实现了手机银行App扫描微信收款码的支付功能。接下来,这种合作还会深化。, 同时,微信小程序正逐步支持云闪付支付,首批上线包括微信读书、腾讯视频、猫眼、京东、步步高、瑞幸等小程序的部分场景,该能力已于9月22日启动灰度测试。
, 【CNMO新闻】9月30日,据微信派消息,腾讯微信支付宣布,已与银联云闪付App正式实现线下条码的互认互扫,用户可于全国省会城市通过云闪付App扫描微信收款码完成支付。另一方面,云闪付App已全面支持Q币、QQ音乐和腾讯视频的充值服务。
当页面滚动时,如何动态切换布局/样式
1. 添加滚动事件的监听/注销
//在componentDidMount,进行scroll事件的注册,绑定一个函数,让这个函数进行监听处理
componentDidMount() {
window.addEventListener('scroll', this.bindHandleScroll)
}
//在componentWillUnmount,进行scroll事件的注销
componentWillUnmount() {
window.removeEventListener('scroll', this.bindHandleScroll);
}
bindHandleScroll = (event) => {
}
2. 在state中添加参数,滚动页面时更新数据
更新参数后,设置样式。可以直接更新样式,也可以动态修改className然后在css文件中添加动态样式。
bindHandleScroll = (event) => {
// 滚动的高度
const scrollTop = (event.srcElement ? event.srcElement.documentElement.scrollTop : false)
|| window.pageYOffset
|| (event.srcElement ? event.srcElement.body.scrollTop : 0);
this.setState({
hasVerticalScrolled: scrollTop > 10
})
}
render() {
return (
<div className="header-container" style={{backgroundColor:this.state.hasVerticalScrolled?'#ffffff':'transparent'}}>
<div className="headerTitle-container">
<img className={`headerTitle${this.state.hasVerticalScrolled ? '-scrolled' : ''}`}></img>
</div>
</div>
);
}
完整Code:
import react, { Component } from 'react';
import './style.less';
interface PropsData {
}
interface StateData {
hasVerticalScrolled: boolean;
}
class Index extends Component<PropsData, StateData> {
constructor(props) {
super(props);
this.state = {
hasVerticalScrolled: false
};
}
//在componentDidMount,进行scroll事件的注册,绑定一个函数,让这个函数进行监听处理
componentDidMount() {
window.addEventListener('scroll', this.bindHandleScroll)
}
//在componentWillUnmount,进行scroll事件的注销
componentWillUnmount() {
window.removeEventListener('scroll', this.bindHandleScroll);
}
bindHandleScroll = (event) => {
// 滚动的高度
const scrollTop = (event.srcElement ? event.srcElement.documentElement.scrollTop : false)
|| window.pageYOffset
|| (event.srcElement ? event.srcElement.body.scrollTop : 0);
this.setState({
hasVerticalScrolled: scrollTop > 10
})
}
render() {
return (
<div className="header-container" style={{backgroundColor:this.state.hasVerticalScrolled?'#ffffff':'transparent'}}>
<div className="headerTitle-container">
<img className={`headerTitle${this.state.hasVerticalScrolled ? '-scrolled' : ''}`}></img>
</div>
</div>
);
}
}
export default Index;
作者:唐宋元明清2188 出处:http://www.cnblogs.com/kybs0/
站长推荐
1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云
2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入
链接: http://www.fly63.com/article/detial/9303
背景是这样的,母亲节的时候,我们有个需求就是用户可以长按或者点击一个按钮进行截图后去分享我们的活动,然而我们的图片例如头像,采用又拍云做 cdn 优化,所以意味着图片的链接跟主页面所在域名不一样,当需要需要对 canvas 图片进行 getImageData() 或 toDataURL() 操作的时候,跨域问题就出来了。
对于跨域的图片,只要能够在网页中正常显示出来,就可以使用 canvas 的 drawImage() API 绘制出来。但是如果你想更进一步,通过 getImageData() 方法获取图片的完整的像素信息,则多半会出错。
举例来说,使用下面代码获取 github 上的自己头像图片信息:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
context.drawImage(this, 0, 0);
context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
结果在 Chrome 浏览器下显示如下错误:
Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.
Firefox 浏览器错误为:
SecurityError: The operation is insecure.
如果使用的是 canvas.toDataURL()方法,则会报:
Failed to execute ‘toDataURL’ on ’htmlCanvasElement’: Tainted canvased may not be exported
原因其实都是一样的,跨域导致。
那有没有什么办法可以解决这个问题呢?
可以试试 crossOrigin 属性。
html crossOrigin 属性解决资源跨域问题
在 html5 中,有些元素提供了支持 CORS(Cross-Origin Resource Sharing)(跨域资源共享)的属性,这些元素包括 ,,“ 等,而提供的属性名就是 crossOrigin 属性。
因此,上面的跨域问题可以这么处理:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.crossOrigin = '';
img.onload = function () {
context.drawImage(this, 0, 0);
context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
增加一个 img.crossOrigin = ” 即可,虽然 js 代码这里设置的是空字符串,实际上起作用的属性值是 anonymous。
crossOrigin 可以有下面两个值:
关键字 | 释义 |
---|---|
anonymous | 元素的跨域资源请求不需要凭证标志设置。 |
use-credentials | 元素的跨域资源请求需要凭证标志设置,意味着该请求需要提供凭证。 |
其中,只要 crossOrigin 的属性值不是 use-credentials,全部都会解析为 anonymous,包括空字符串,包括类似 ‘abc’ 这样的字符。
例如:
img.crossOrigin = 'abc';
console.log(img.crossOrigin); // 结果是'anonymous'
另外还有一点需要注意,那就是虽然没有 crossOrigin 属性,和设置 crossOrigin=”use-credentials” 在默认情况下都会报跨域出错,但是性质上却不一样,两者有较大区别。
crossOrigin 兼容性
IE11+(IE Edge),Safari,Chrome,Firefox 浏览器均支持,IE9 和 IE10 会报 SecurityError 安全错误,如下截图:
crossOrigin 属性为什么可以解决资源跨域问题?
crossOrigin=anonymous 相对于告诉对方服务器,你不需要带任何非匿名信息过来。例如 cookie,因此,当前浏览器肯定是安全的。
就好比你要去别人家里拿一件衣服,crossOrigin=anonymous 相对于告诉对方,我只要衣服,其他都不要。如果不说,可能对方在衣服里放个窃听的工具什么的,就不安全了,浏览器就会阻止。
下载到本地
IE10 浏览器不支持 crossOrigin 怎么办?
我们请求图片的时候,不是直接通过 new Image(),而是借助 ajax 和 URL.createObjectURL() 方法曲线救国。
代码如下:
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var url = URL.createObjectURL(this.response);
var img = new Image();
img.onload = function () {
// 此时你就可以使用canvas对img为所欲为了
// ... code ...
// 图片用完后记得释放内存
URL.revokeObjectURL(url);
};
img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();
此方法不仅 IE10 浏览器 OK,原本支持 crossOrigin 的诸位浏览器也是支持的。
也就多走一个 ajax 请求,还可以!
根据,根据实践发现,在 IE 浏览器下,如果请求的图片过大,几千像素那种,图片会加载失败,我猜是超过了 blob 尺寸限制。
后来采用的解决方案是:把图片下载到本地(前端或者是后端都可以,最后采用我前端来做)
getAvator(user, func) {
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes.
var xhr = new XMLHttpRequest();
xhr.open('GET', user.avatar, true);
xhr.responseType = 'blob';
xhr.send()
xhr.onload = function(e) {
const {target} = e
const {status, response, readyState} = target
if (readyState == 4 && status == 200) {
var blob = response;
var img = document.createElement('img');
img.classList.add("avatar")
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
img.src = base64data;
};
func && func(img)
}
};
},
设置 nginx 代理
如 php 添加响应头信息,* 通配符表示允许任意域名:
header("Access-Control-Allow-Origin: *");
或者指定域名:
header("Access-Control-Allow-Origin: www.zhangxinxu.com");
html2canvas 真实采坑记和建议
如果使用 vue 做数据渲染,不要在生成页做太多数据处理的操作,提前把动态数据处理好,否则即便用 $nextTick 也会有在生成图片时数据不完整的情况
引用 CDN 上的图片,需要设置 useCORS 为 true,同时要保证所有图片加载完成后再生成,可使用 new Imaage 做预加载和判断是否全部 load
用背景 background,生成的图片清晰度不够,会模糊;用 img 引入的方式可避免这个问题
在 iOS 系统的 13.4.1,无法生成图片,需要退回到 1.0.0-rc.4 版本,不要使用 1.0.0-rc.5 版本,issues 地址:https://github.com/niklasvh/html2canvas/issues/2205
可把生成的图片设置透明度 opacity 为 0,盖在原有元素之上,便于在微信保存,不会因为生成的图和原有元素略微有差距,而抖动。
来自:https://www.cnblogs.com/Jomsou/archive/2020/07/18/13334741.html
站长推荐
1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云
2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入
链接: http://www.fly63.com/article/detial/9480
1. reduce()语法
// total 必需。初始值, 或者计算结束后的返回值。
// currentValue 必需。当前元素
// currentIndex 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象。
// initialValue 可选。传递给函数的初始值
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
2. 数组求和
var aa = [1,2,3,4.1,5,'2','9'];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
return total+ Number(currentValue)
},0)
console.log(bb); // 26.1
3. 数组最大值
var aa = [1,2,3,4.1,5,'2','9'];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
return Math.max(Number(total),Number(currentValue))
})
console.log(bb); // 9
4. 数组去重
var aa =[1,2,3,4.1,5,5,'2','2','9',1];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
if(total.indexOf(currentValue) == -1) {
total.push(currentValue);
}
return total;
},[])
console.log(bb); // [1, 2, 3, 4.1, 5, "2", "9"]
5. 计算数组中每个元素的出现的次数
var aa = [1,2,3,4.1,5,5,2,2,9,1];
var bb = aa.reduce(function(total,currentValue,currentIndex,arr){
total[currentValue]?total[currentValue]++:total[currentValue]=1
return total
},{})
console.log(bb);// {1: 2, 2: 3, 3: 1, 5: 2, 9: 1, 4.1: 1}
站长推荐
1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云
2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入
链接: http://www.fly63.com/article/detial/9530
抱怨 JS 疲劳就像是在抱怨人类发明了太多解决问题的工具:从邮件到飞机到宇宙飞船。
上周我在 NebraskaJS 2017 会议上做了一个和这个话题极其类似的演讲,我也收到了许多积极的反馈,所以我就想这个演讲也可以写成一篇文章发表出来,让更多的人知道,并帮助他们应对 JS 疲劳,理解我们行业的真相。这篇文章的目的是希望改变你对软件工程行业的普遍的看法,助你在你可能工作的领域上一臂之力。
激励我写下这篇文章并且彻底改变我生活的一个原因是 Patrick McKenzie 写的这篇很赞的文章,文章名叫《请不要自称程序员和一些职业生涯建议》。强烈推荐你阅读下上面这篇文章。本文的大部分内容都是基于 Patrick 的那篇关于 JavaScript 生态系统的文章的建议,其中也夹杂了最近几年我在科技行业工作的一些想法。
第一个章节可能会有点哲学化,但是我保证绝对值得一读。
我们行业的真相 101
就像 Patrick 在 他的文章 里写到的,我们先从一些最基础、最根本的真相说起:
软件是用来解决业务问题的
实事就是这样。软件存在的意义并不是用来取悦我们程序员的,并不是为了让我们写出漂亮代码的,也不是为科技行业创造就业机会的。实际上,软件的存在扼杀了太多的工作岗位,其中也包括我们的,这就是为什么基本工资在未来的几年将会变得更加重要,但是这就完全是另一个话题了。
我这样说很抱歉,但是归根结底原因在于:在软件工程中(其他行业也是如此)只有两样东西至关重要:
支出和收益
支出削减的越多,收益提升的越多,那么你的价值就越大,削减支出、提升收益最通用的一个方法就是用机器代替人工,从长远来看,这种方法是更有效的,而且支出也更少。
你不是被雇佣来写代码的
科技不是目的。没有人关心你使用的是什么编程语言,没有人关心你的团队选择的是什么框架,没有人关心你的数据结构有多么优雅,也没有人关心你的代码写得有多漂亮。人们唯一关心的是:你的软件支出是多少,产生的收益是多少,仅此而已。
写出漂亮的代码对于你的客户而言没有任何卵用。我们之所以要写漂亮的代码,是因为长远来看这样会更高效,能够减少支出,增加收益。
我们努力避免 bug 不是说我们重视正确性,而是我们的客户重视正确性。如果你曾经遇到过一个 bug 成为了一个特性的话,那么你就知道我在说什么了。这个 bug 确实存在,但是我们不会去修复。出现这种情况并不是说我们的目的就是制造 bug,我们的目的是创造价值。但是如果我们的 bug 能够使客户开心,能够提升他们的收益,我们也能达成我们的目标,如此皆大欢喜,何乐而不为呢。
可重复使用的太空火箭、自动驾驶汽车、机器人、AI:这些东西之所以存在,并不是因为我们觉得它们很酷,而是因为在它们的背后有商业利益存在。我并不是说这些东西背后的那群人只在乎金钱,我确定他们也认为这东西很酷,但事实是,如果没有经济利益或者说没有潜在的经济价值,这些东西是不会存在的。
也许我不应该将这一章节取名为“我们行业的真相 101”,也许应该取名为“资本主义真相 101”。
说到我们的目标——减少支出提升收益——我认为作为程序员的我们应该更加关注需求和设计,积极思考,积极参与业务决策,这就是为什么了解我们正在开展的问题领域变得极其重要。之前你有多少次在你的经理或商务人士没有考虑到的某些边缘案例中想到应该发生什么?
1975 年,Boehm 做过一项研究,研究发现,软件中 64% 的错误都是由设计引起的,只有 36% 的错误是代码错误。另一项叫做 “高阶软件——软件定义方法论” 的研究也显示:在 NASA 的阿波罗计划中,73% 的错误都是设计错误。
设计和需求存在的唯一目的就是定义我们将要解决的问题,而解决问题就能创造收益。
没有了需求或设计,编程就是往一个空的 text 文件里面添加 bug。
- Louis Srygley
这个原则同样适用于 JavaScript 生态系统的工具。Babel、webpack、react、Redux、Mocha、Chai、Typescript,所有这些工具之所以存在就是为了解决对应的问题,我们要理解它们要解决的是什么问题,要仔细思考什么时候需要这些工具,否则,我们就会感到 JS 疲劳,因为:
当我们使用我们不需要的工具来解决根本就不存在的问题的时候,JS 疲劳就出现了。
正如 Donald Knuth 曾今说的:“过早优化是万恶之源”。请记着,软件的存在是为了解决相应的业务问题,大部分的软件其实都挺令人厌烦的,既没有多强的扩展性,也没有高性能约束。要专注于解决业务问题,专注于减少支出、提升收益,这才是需要关注的焦点。只有在当你需要优化的时候才去优化,否则,软件可能会增加一些不必要的复杂性,而这些复杂性会增加支出,并且不能产生足够的收益来抵消这些支出。
这就是为什么我认为应该在我们的工作当中应用 测试驱动开发 原则。我说的测试驱动开发并不是说仅仅去做测试。我说的是在问题暴露之前将其扼杀在摇篮里。这才是 TDD 要做的。正如 Kent Beck 说的“TDD 减少了恐惧”,因为它能够指导你的开发节奏,允许你慢慢地逐步解决你的问题,一步一个脚印,一次解决一个问题。当我们要使用新的技术时,这样做同样也会减少恐惧。
一次解决一个问题同时也降低了 分析麻痹,举个栗子,就好比你打开了 Netflix,你本可以看一些视频的,但是却花了三个小时来决定看什么。一次解决一个问题的方式可以缩小我们做决定的范围,缩小了做决定的范围我们的选择就会相对减少,选择减少了我们就降低了分析麻痹。
不知道你有木有想过,如果只有几个可看的电视频道,决定看哪个频道会变得多么简单?如果家里只有几张游戏盘,决定玩儿哪个游戏会变得多么简单?
那么对于 JavaScript 而言呢?
截止到我写这篇文章时,NPM 上有 489,989 个包,第二天将会有差不多 515 个包在上面发布。
我们使用、抱怨的这些包都是有一个历史出发点的的,为了理解我们为什么需要这些包,我们必须理解这个历史出发点:它们是用来解决问题的。
Babel、Dart、CoffeeScript 和其他转义器之所以会出现,是因为我们不仅仅使用 JavaScript 写代码,但是我们又想使其能够在浏览器中正常运行。Babel 甚至能够使我们使用 JavaScript 新版本语法写的代码在旧版本浏览器中运行,因为众所周知,不同版本的 ECMA 规范在各个浏览器中的兼容是一个很大的问题。尽管现在 ECMA 规范已经越来越可靠,但是我们仍然需要 Babel。如果你想了解更多关于 Babel 的相关知识,我强烈推荐你读读 这篇由 Henry Zhu 写的很赞的文章。
像 Webpack 和 Browserify 这样的模块化打包工具也有它们存在的理由。想必你们依然记得,曾几何时,我们使用大量的 script
标签将脚本引入使其能够正常运行。这样做的结果就是污染了全局命名空间,当一个脚本依赖另一个脚本时,很难合理地将它们整合起来。为了解决这个问题,Require.js
诞生了,但是它仍然有它自己的问题:它不够简单,语法也会引起其他问题,正如你在这篇文章中看到的。然后 Node.js 借鉴了 CommonJS
的 import,这种 import 是同步的,简单整洁,但是我们仍然需要一种可以在浏览器中运行的方式,这就是为什么我们需要 Webpack 和 Browserify 的原因。
Webpack 确实解决了很多问题,比如可以像处理 JavaScript 依赖那样处理 CSS、图片和许多其他的资源。
前端框架确实有点复杂,但是由于它们的存在,使得我们写代码时减少了同步加载,如此一来,我们就不必担心 DOM 操作,甚至也不用和那些乱七八糟的浏览器 API(JQuery 已经解决了这个问题)直接打交道,众所周知,浏览器的兼容性处理错误百出,而且效率低下。
这就是我们在计算机科学中一直在做的事情。我们使用低级抽象,并在其上构建更多的抽象。我们应该更多考虑的是,我们的软件应该如何运行,而不是怎么让它运行,这样的话,才能更高效。
但是所有这些工具都有一个共同之处:它们之所以存在是因为 web 平台发展太快了。如今任何地方都有 web 技术的存在:web 浏览器,桌面应用,电话应用,甚至手表应用。
这个革命性发展同样也暴露出了我们需要解决的问题。比如,渐进式 web 应用(PWA),它们之所以存在不是因为它们很炫酷,不是因为作为程序员的我们乐于写 PWA。请牢记本文的第一节:PWA 之所以存在,是因为它们创造了商业价值。
通常情况下,标准的制定速度并没有那么快,因此,针对对应的问题我们需要自己寻求解决方法,这就是为什么有一个活跃度高、有创造力的社区是一件很 nice 的事情。我们不是在解决问题,就是在去解决问题的路上。当然,我们也会顺其自然。
适用于我们的工具会更好地成长,获得更多的贡献者,更快地发展,有时一些工具最终将融合来自于其他工具的优秀想法,并且变得比它们更受欢迎。这就是我们演变的进程。
拥有越多的工具,我们就会拥有越多的选择。想必你还记着 UNIX 思想,它主张我们在编程时,一次只做一件事情,而且要将它做到极致。
我们可以清晰的看到这种思想在 JS 测试环境中重现,比如,我们使用 Mocha 跑测试,使用 Chai 做断言,而在 Java 中,JUnit 把这些事情全部包揽了。这就意味着,如果你在使用某一个工具的过程中遇到了问题,并且发现另一个工具更适合我们的话,那么我们就可以直接简单的替换掉之前的工具就可以了,其他工具的优势我们依然能够保留。
UNIX 思想同时主张我们应该去写能够“和谐相处”的程序。这正是我们在做的!比如说 Babel、Webpack 和 React。同时使用它们完全能够正常运行,但是我们并不需要使用一个工具而去依赖另一个工具。比如我们在测试环境中使用 Mocha 和 Chai,那么我们也可以安装 Karma 在多种环境中来跑同样的测试。
如何应对
针对正在遭受 JS 疲劳的同学,我的第一个建议是:你要清醒的认识到你并不需要掌握所有东西。有时我们会一次性学习过多的知识——甚至当我们并不需要的时候,这样做只会增加疲劳感。你喜欢的领域你要保持积极的学习动力,可以深入了解,而对于其他的知识,你大可保持慵懒的态度。我这里说的慵懒不是让你懒惰,而是在你需要某些知识的时候再去学习。当你遇到了问题,且需要使用某项知识技能来解决的时候,直接现学就可以了。
另一个重要的建议是:脚踏实地,从头开始。在你使用任何 JavaScript 框架之前,请确保你对原生 JavaScript 学习的已经足够透彻。这是你掌握 JavaScript 并能够将其“玩弄于鼓掌之中”的唯一途径,否则,当你遇到了你之前从来没有见过的问题时,你就不知道该如何下手。学习核心的 web 技术——CSS、HTML5、JavaScript和计算机科学基础,甚至是 HTTP 协议的工作原理——将会有助于你快速掌握任何其他的技术。
但是,请务必不要用力过度。偶尔你要挑战一下自己,亲自动手做一些项目。正如 Sacha Greif 在这篇文章里写到的那样:花费过多的时间学习基础知识就像你要学习游泳时总是在学习流体动力学。学到一定程度以后,你就应该跳到游泳池里去尝试游泳。
同时,请务必不要拘泥于一项技能。我们现在可用的技术其实在过去都早已被发明出来了。当然,它们特性不同,名字不同,但是,本质上它们都是相同的。
如果你看看 NPM 的话,它也不是什么新技术,很早之前就有 Maven Central 和 Ruby Gems 了。
用来转义代码的 Babel,也是借鉴了早期一些非常出名的编译器的原则和理论,比如 GCC。
甚至 JSX 也不是什么新想法。E4X(ECMAScript for XML)10 多年前就存在了。
那么现在你可能会问:“那 Gulp、Grunt 和 NPM 脚本又如何呢?”额,好吧,很遗憾的告诉你,这些问题 GNU Make 在 1976 年都已经解决了。实际上,现在仍然有大量的 JavaScript 工程在使用 GNU Make,比如 Chai.js。但是我们不会那样做,因为我们是喜欢复古的潮人。我们使用 make
,因为它解决了我们的问题,正如我们之前讨论过,这就是你的目标所在。
如果你真的想要理解某项技术,想要在面对任何问题时都能够得心应手,那么,请深入了解。成功最关键的一个因素就是好奇心,所以请深入了解你喜欢的技术。尝试自下而上的理解它们,每当你认为某些东西如“魔法”一般时,那么请通过探索代码库来揭开它的神秘面纱。
在我看来,说到学习这块儿,Richard Feinman 的这句名言最适合不过了:
我创造不了的东西,我理解不了
再来看看下面这句,这是 Richard 在同样的一块儿黑板上写下的:
对于已经存在答案的问题要知道如何解决
是不是很赞?
当 Richard 说这些话的时候,他正在讨论的是关于获取理论结果并如何复现的问题,但是我认为,该原则同样适用于软件工程。能够解决我们的问题的这些工具已经被发明出来了,它们已经存在了,所以我们也应该能够自己来实现它们。
这正是我喜欢 Egghead.io 中一些视频的原因,视频中 Dan Abramov 解释了如何从头开始实现 Redux 中存在的某些功能,或者教你如何构建自己的 JSX 渲染器。
那么我们为什么不去尝试着自己来实现或者去 GitHub 上阅读代码库理解它们的原理来实现这些东西呢?我确定你一定能够发现很多有用的知识。评论和 demo 也许会撒谎,也许会误导,但是代码不会。
另一个我们在这篇文章中谈论的最多的话题是:你不应该超前你自己。遵循 TDD 原则,一次只解决一个问题。你被雇佣是来降低成本提升收益的,你所做的都是为了解决问题,这就是软件存在的意义。
既然我们喜欢拿我们自身的角色和土木工程相关的作对比,那么就让我们快速对比下软件开发和土木工程,就像Sam Newman 在《构建微服》中做的那样。
我们喜欢自称“工程师”或“架构师”,但是这样真的好么?我们一直在为不到一百年前的计算机开发我们所知的计算机软件,而竞技场都存在大约两千年了。
还记得最近一次看到一座桥坍塌是什么时候吗?还记得最近一次你的手机或浏览器奔溃是什么时候吗?
为了更好的解释,我借用一个我比较喜欢的栗子。
这是美丽惊艳的巴塞罗那。
当我们从这个距离看这座城市的话,它开起来和世界上的其他城市一般无二,但是当我们从上面俯瞰时,巴塞罗那看起来是这个样子的:
正如你看到的,每一个块儿都有着相同的尺寸,所有的块儿都有条不紊的排列着。如果你曾经去过巴塞罗那的话,你一定知道穿越这座城市有多么爽,知道它运行的多么良好。
但是坐在飞机上俯瞰巴塞罗那的人无法预知两百年或者三百年后它会成为什么样子。城市里的人们进进出出,他们要做的是让城市随着时间的流逝有机地成长、适应。他们必须做好应对变化的准备。
同样的事情也发生在软件方面。软件更新迭代很快,会经常需要重构,需求也会频繁的变更,这完全在我们的预期之外。
所以,不要把自己当做软件工程师,要把自己当做城市规划者。让你的软件有机成长,按需适应。兵来将挡,水来土掩,问题来了就去解决,但是要确保一切都有其所在。
在软件领域做这些事情比在城市里做这些事情要容易的多,因为软件是灵活的,土木工程并不是,在软件世界里,我们的“建筑时长”就是编译时长。在巴塞罗那我们不能通过简单地毁掉建筑给新的建筑腾出空地儿,但是在软件世界里我们可以非常简单的实现。我们随时可以推翻重做,随时可以做实验,我们想构建几次就构建几次,时间花费也就那么几秒钟,但是我们思考的时间却比构建的要多得多。我们的工作是纯智力型的。
所以把自己当做城市规划者,让你的软件按需成长、适应。
通过这样做,你就能够更好的抽象,也会知道在什么合适的时间来采用它们。
正如 Sam Koblenski 所说:
抽象只适用于合适的语境,而合适的语境是随着系统的发展而发展的。
有时候我经常会看到这种现象:有些同学在学习一项新技术时会去寻找模板,但是在我看来,当你开始学习的时候,应当避免使用模板。当然,如果你已经有了一定经验,那么模板和生成器还是很有用的。模板剥夺了大部分的控制权,因此你就学不到如何去新建一个工程,你也无法准确理解每个代码片段适合哪里。
当你无法轻轻松松地把事情搞定,当你感受到的都是苦苦的挣扎时,也许是时候另辟蹊径了。我们的宗旨是力争懒惰,你应该为了以后不工作的目标而去工作。如此一来,你就会有更多的自由时间去做其他的事情,从而减低了成本,提升了收益,所以这也是你达成目的的另一条途径。你不应该没头没脑的努力工作,你要更加聪明的工作。
也许有些人也会拥有你现在的烦恼,但是如果没人这样做的话,那么你的机会就到了,你可以找到你自己的解决方法,可以给其他人伸出援助之手。
但是有时候在你没有看到别人做的更优秀之前,你并不会意识到其实你也可以做的更高效。这就是与人交流的重要性。
通过和其他人交流,你可以分享你的经验,为对方的职业生涯提供帮助,也能发现能够提升我们工作流的新工具,而且更重要的是,你能够学到解决问题的方法。这就是我喜欢阅读分享公司解决问题方法的文章的原因。
尤其是在我们的领域里,我们总是认为 Google 和 StackOverflow 能够回答我们的所有问题,但是我们仍然有必要知道我们要问的问题。我确定会有这么一种场景:你遇到了一个你无法解决的问题,因为你无法准确的知道发生了什么事情,所以你自己都不清楚你应该问什么问题。
但是如果我需要用一个建议来总结整篇文章的话,那就是:
解决问题。
软件不是魔法箱,也不是一首诗(很不幸)。它的存在是为了解决问题,提高人们的生活水平。软件的存在是为了让世界向前发展。
年轻人,该你出动解决问题了。

毫无疑问,数字化的智能城市是未来的潮流。但是通往一个更加紧密联系的市政当局的道路还很不明朗。尽管在美国的主要大都市地区有一些共同的挑战,没有两个城市拥有相同的基础设施、治理、态度、预算或需求。芝加哥的处事方式与达拉斯、亚特兰大或旧金山的处事方式不同。沐鸣平台
围绕着通过数字化转型建设智慧城市,有很多问题。发展的首要解决方案是什么?谁是真正的客户?这些数据会发生什么?这些答案将决定二十年后的世界面貌。它看起来肯定会和现在很不一样。
首先,考虑为使城市更加友好而提出的各种数字转换。爱立信网络和技术战略主管鲍勃•格塞尔(Bob Gessel)证实,最初的实施将取决于这座城市以及他们试图解决的问题。爱立信押注交通运输将成为许多城市的领跑者。“我们花时间了解交通和流动性,以帮助城市管理现有和未来的交通。其目标是测量基础设施并向用户提供数据,以便他们能够基于态势感知更好地导航。我们称之为互联流量云。该公司希望帮助城市和通勤者找到新的方法,将数据处理成节省时间、燃料和能源的新见解。
智能汽车、建筑和城市将同时出现
除了与制造商在车辆内的仪表方面合作,物联网创新者还关注车辆对车辆和车辆对基础设施的通信。事实上,智能汽车更有可能在智能城市中激增。Bob表示,联网的城市将为自动和半自动汽车生成新的数据。“这样就有可能确定他们将在哪里开车,并在安全区域进行测试。”沐鸣总代理
事实上,打个比方,公路可能很快就会被物联网堵塞。在任何智能交通解决方案中,自动报告道路状况的车辆都将发挥关键作用。当旧的路边灯被LED灯取代时,新的灯可能还包含空气质量传感器。来自这些边缘设备的数据可以为居民和游客提供提前通知,他们可能需要调整旅行计划、户外活动和药物,以应对环境威胁。
在启动阶段,一些解决方案专注于解决终端用户层次上的特定问题。在最近的北德克萨斯物联网黑客松(North Texas IoT hackathon)上,智慧城市和联网汽车是创新的重要领域。Yeshvik Solutions的校长Yeshwant Muthusamy博士提出了一个物联网系统,该系统将使在大学停车场和车库内停车更容易、更安全。其他创新公司的目标是为游客和新居民提供交互式电视或智能手机应用,以促进基于地理空间定位的当地活动和商业活动。沐鸣登陆地址
数字化转型为智慧城市
Yeshwant指出,美国并没有在向互联城市转变的道路上走在前面,但人们的态度正在转变。“智能城市已经在美国以外的地方流行起来,我认为它正在发生变化,并开始在美国表现出来。“这种延迟的一个原因是,买进可能是一个挑战。有许多利益攸关者参与其中,包括市议会、公共机构的民选官员、商业领袖和其他感兴趣的政党。“提出解决方案的人有责任识别客户,并就节约成本或创收的结果进行沟通。”你必须迎合关键的方面。碰撞村首席执行官、黑客松组织者Tahir Hussain表示同意。“利益相关者是城市,但客户是看到愿景和价值的人。”

TechRepublic上有一篇名为《DevOps实施的十大挑战》的文章(链接如下)。那么挑战是什么呢?他们列出了标准的东西,比如文化和技能,计划和工具。沐鸣测速注册
如果不是因为我写的或发表的关于类似主题的文章比我愿意承认的要多,我会批评这个列表的愚蠢。我记得有三个月的时间,我被要求收集关于如何让DevOps工作的不同见解,我写的每一篇关于这个主题的文章似乎都集中在文化、技能和计划上,而文化总是占据了大部分的焦点。这里只是几个例子:
协作和社区是DevOps在2017年取得成功的关键
通过DevOps过渡的三个最艰难的阶段
应用生命周期管理需要统一的DevOps方法
这个问题比DevOps转换更根本
这是我对这类文章的看法。一个组织缺乏技能、计划和适当的工具不会导致DevOps采用失败。这些东西的缺乏是导致组织失败的原因。当人们谈论“文化”时,他们谈论的是一种普遍的心态。如果你的IT部门是由一群人组成的,他们向不同的方向推进,那么问题不在于采用DevOps,而在于整个IT部门。沐鸣怎么当代理?
我一直认为,切换到DevOps之所以有效,与敏捷的原因是一样的,而这与方法本身无关。转向DevOps或敏捷的原因是,它让部门没有做测试,没有做质量控制,没有雇佣正确的人,没有使用正确的工具来开始正确地做所有这些事情。如果那些混乱的组织将所有这些事情付诸行动,但是保持开发和操作之间的障碍,他们可能会看到所有相同的好处,如果他们做了所有这些事情,但是坚持瀑布式开发方法,他们也会看到进展。
必须有一个方法
我不是那种到处鼓吹某种方法论的人,因为我不相信其中任何一种方法比其他方法更有效。我所知道的是,没有方法论的组织肯定会失败,所以当没有方法的组织采用一种方法时,他们就会成功。沐鸣下载
TechRepublic的文章是对的。如果你的组织不解决上面提到的十个挑战,你的DevOps实施将会失败。但是,如果您的组织正在与本文所讨论的这十个挑战作斗争,那么无论您是否在实施DevOps,您的组织都注定要失败。

AWS云架构副总裁Adrian Cockcroft认为,构建云系统的最大挑战之一在于构建事物的人方面。除了在亚马逊的工作,科克罗夫特还在架构Netflix的云战略方面发挥了关键作用。在Netflix崛起后,他经常在首席信息官圆桌会议上发言,大家总是问他这些超级明星工程师是从哪里来的。“好吧,我们都是从你那儿雇来的,”他会回答。沐鸣注册网站
多年来,科克罗夫特一直在思考是什么让Netflix如此吸引顶尖人才。其中一个因素是Netflix非常进步的开源项目,它让开发者可以自豪地与更大的开发者社区分享。这也有吸引招聘人员的危险,而招聘人员可能会把程序员挖走。沐鸣平台
薪酬和财务或声誉
为了解决这个问题,Netflix制定了一个非常积极的补偿计划。每年都会对程序员进行评级,并根据雇佣具有类似才能的人的成本进行补偿。这在许多关注百分比增长的企业中可能不会实现。科克罗夫特说:“我不知道还有哪家公司每年都这样做。”
另一个好的做法是通过组织一个“杰出工程师”或“研究员”圈子来确立重要人才的地位。一旦这个圈子足够大,成员们就可以提名其他人加入这个团体,这个团体就变成了某种精英俱乐部。进入这个团队的方法就是为其他杰出的工程师提供价值。随着时间的推移,这些杰出的工程师会作为一个团队相互了解,从而建立凝聚力和忠诚度。沐鸣登录