算法
最小和
给定一个数组,求三堆的和尽量最小。
这不应该去使用贪心算法,做类似瀑布流的一个布局。应该用完全背包算法。
贪心算法解法
var input = [1,2,3,4,5,6,7,8,9]
const findMinIndex = function (arr) {
var min = arr[0];
var minIndex = 0;
for (var i = 1; i < arr.length; i++) {
if (min > arr[i]) {
minIndex = i;
min = arr[i];
}
}
return minIndex
}
Array.prototype.findSum = function (n) {
if (n > this.length) return false;
var arr = new Array(n);
var sumArr = new Array(n)
for (let i = 0; i < n; i++) {
arr[i] = [this[i]];
sumArr[i] = this[i];
}
if (n === this.length) return arr;
for (let i = n; i < this.length; i++) {
var minIndex = findMinIndex(sumArr);
arr[minIndex].push(this[i]);
sumArr[minIndex] += this[i];
}
return arr;
}
input.findSum(3);
// output [[1,5,9],[2,6],[3,7],[4,8]]
// 实际上随意想想这也不是最优解
背包解法
const knapsack = (weights:number[], total:number) => {
var n = weights.length;
var f = [[]];
f[-1] = new Array(total+1).fill(0);
for(var i=0; i<n; i++){
f[i] = new Array(total).fill(0);
for(var j=0; j<=total; j++){
if(j < weights[i]){
f[i][j] = f[i-1][j];
}else{
f[i][j] = Math.max(f[i-1][j], f[i-1][j-weights[i]] + weights[i]);
}
}
}
var resData = [],
j = total;
for(var i=n;i--;){
if(f[i][j] > f[i-1][j]){
resData.push(weights[i]);
j -= weights[i];
weights.splice(i, 1);
}
}
return {
resData,
arr: weights
}
}
const findSum = (n:number, arr:number[]) => {
var total = 0;
arr.map(item => {
total += item;
});
var avg = Math.floor(total / n);
var resData = [];
for(var i=0;i<n;i++){
var res = knapsack(arr, avg);
resData.push(res.resData);
arr = res.arr;
}
}
findSum(3, [1,2,3,5,6,8,9])
前端架构
为什么要做前端架构
前端开发的目标是为了实现高效高质量的推进业务。如何让一个团队达到这个目标?需要对现有的目标做一个拆分。我觉得应该分为:业务 + 技术 + 团队 + 后评估系统来完成。
业务
达成业务是目标,那么业务达成分为两方面:拆解现有的业务需求并完成上线;能支撑未来至少半年的业务发展。前端在这方面的贡献在于技术输出,需要用一定的技术能力达成这个目标。也就是说技术方案需要能达成当前的业务需求并能支撑未来的技术发展。
以我负责的业务为例,我们的业务需要满足用户的需求,将业务放在了五个载体上,这就是五个端,这五个端分别承载着不同的用户习惯和目标。微信端是在微信的公信力下构建快捷的服务承接;小程序是承载我们的大背景下不能放在微信服务体系下的商业服务;自助机是在服务落地的地方承接线上无法完成的功能;APP 是形成一定的用户习惯的服务承接;PC 后台系统是要展示更多的信息,便捷的操作处理的功能。不同端之间前端不仅仅是做粘合剂的作用,更多的是提高业务门槛,大统对于前端来说是提升开发效率,工作更加便捷,但是对于业务来说却是降低了实现成本,降低了技术壁垒。
业务的不同侧重点会将服务承接端进行划分,端只是达成业务的方式,而前端在业务中的承载的角色是沟通业务与用户之间的展示和交互,能向用户更加准确的表达业务。
技术
技术要达到上述目标,肯定需要技术架构来作为支撑,技术需要去完成业务目标,并留出足够多的扩展性支撑,这个时候就应该根据业务形态去构建对应的技术架构作为支撑。
对于前端来说这里的考虑会有:其他同类型业务是怎么完成的,我们的业务和别的业务有什么不同,适合用什么端来展示,适合什么样的前端架构,如何和其他技术方合作,使用什么技术框架来完成,周边需要怎样的服务设施,如何与现有的技术方案融合,如何用最低的成本去实现等等,这些考量的问题会最终决定业务应该用什么样的技术架构去完成。
但是技术架构是会先考虑业务的情况,优先考虑业务的实现和未来的扩展,在这个的基础上,还需要考虑团队的情况,因为毕竟一个业务可能会需要协作完成,所以技术架构考虑了业务的基础上,要尽量考虑前端团队最终的输出和完成情况。
团队
我认为技术架构又是由团队的平均水平决定的,不是由最高水平决定,我们可以由最高水平的同学去构建底层和架构,让这个技术架构具有更强的各种性质,但是完成业务需求的同学都是平均水平的同学。
所以核心在于提高团队的平均水平,提高团队的平均水平我认为应该分四个阶段:完成业务,了解为什么要这么去完成业务,知识的广度,知识的深度。
最低的要求是要按照一定的规范去完成业务,这个阶段比较重要的是代码的 review,这样才能控制初期的业务完成度的质量,保证开发质量,加深对于业务的理解。
第二个阶段要让大家明白为什么要这么写,带着思考更好的去完成业务,这个阶段最重要的是设计的 review,明白如何去划分模块,更好的结构化自己的代码,提高开发效率
第三个阶段要对前端相关全链路的知识有一定的了解,前至浏览器网络层,后至如何与其他方配合开发,这个阶段最重要的是了解如何定位问题,bug 和线上的故障一定要更快的找准问题,及时解决问题,出现问题第一时间能解决。
第四个阶段需要进入一些细分领域进行深度的学习,一个团队能承接什么样的业务难度是取决于是整个团队的技术能力深度,不取决于某个人,所以需要让团队分出不同方向,然后每个人进行不同方向的深度学习,然后让团队的木桶尽量深。这个阶段是处理高精尖问题,攻坚一些业务难点和技术难点。
关系
上面由目标引发了这些思考,为了完成目标需要上诉的这三个要素,这三者也需要协同来完成目标。所以三者间一定存在着一些关系。我目前的认知认为三者存在以下关系。
业务的实现及未来发展的扩展性需要技术架构来承接,技术架构的扩展性,容错性,低耦合高内聚一定程度决定的能承接多大多复杂的业务。业务的实现由技术来决定,技术架构越来越完善也能承接越来越好的业务。
技术架构一般是由团队的平均水平决定,技术架构能攻坚的难度是由团队的最高水平决定,前端是推进业务的效率及质量需要的是大部分的人去完成,而后者是难度需要的是极少部分的人去完成,这也需要团队中有良好的人员结构。技术架构的演进也将进一步提升团队成员的技术能力。
团队的好坏一定程度是受业务的好坏决定,通过培训和其他的一些方式只能提高团队的水平,而且团队的稳定性也很难提升,好的业务能吸引更优秀的人员加入,也能让内部的同学不断跟着业务的发展所提升自己。并且优秀的业务也能绝大程度的留住优秀的同学,也将进一步提升团队的稳定性。吸引了更多更优秀的同学,业务的完成度也将越来越好。
三者之间应该是一个相互依赖的关系,都是一个正向促进的作用,但是这种正向促进是需要有定性或者定量的方式来评估的,如何评估这三方面做的好或者不好,才能真正发现问题,不断的优化提升。
后评估系统
我们只有通过一系列的定性或者定量的指标衡量之后才能判断我们的上面这三方面做的好还是不好。
评估业务可以通过常规的一些指标,比如PV、UV、转化率,也有一些特性业务形态的评估指标,比如成单率、停留时间、有效点击等。这些都是可以通过前端交互的改进来提升这些业务指标。
技术评估可以通过定性的指标,业务的扩展性,业务的完成度,完成效率。以及一些线上的白屏时间,资源加载时间,js 报错监控情况等等。这些指标能一定程度的反应前端技术架构的稳定性,扩展性等。
团队评估可以通过一些项目管理的指标来衡量,开发周期中有没有 delay,有没有被测试打回,测试过程中千行 bug 率,上线之后的线上 bug 数,线上故障情况,这些指标来反应团队成员的效率及能力素质。
评估系统仅仅是作为一个参考和衡量,不要忘了我们最终想要达到的目标高效高质量的推进业务。高效高质量是一方面,这里用的是推进业务不是完成业务,前端应该具有交互工程的职能。应该从交互的角度给业务提供建议去迭代改进业务,也需要去协调各方资源,推动业务上线。
总结
架构这个东西很虚,很难让人理解,我目前仅仅是能根据自己的认知将架构这个概念,拆解到这些具象化的代名词上,每一个方向上都应该会有很多延伸,业务又会有适合业务形态的业务架构,技术又会有应用场景的技术架构,团队又会有最大向外输入价值的团队架构。这些概念又需要拆解成实实在在的具象化的代名词进一步进行理解,之后会逐渐去落实。