思否编程

思否编程 查看完整档案

北京编辑  |  填写毕业院校思否编程  |  搬砖人 编辑 segmentfault.com/lives 编辑
编辑

思否编程是由中国新一代开发者社区 SegmentFault 思否孵化的在线编程培训平台,通过提升开发者 IT 职业技能,帮助开发者获得成功

思否编程网址:https://ke.sifou.com/
申请成为讲师:https://jinshuju.net/f/HK5r9K

添加编程小姐姐微信:bobonadia

个人动态

思否编程 发布了文章 · 1月14日

前端大数据可视化从入门到实战

作者:小天

大家好,我是小天,从事于一家金融类公司,负责前端架构与大数据可视化相关工作。本篇文章与大家简单聊一下前端与数据可视化。

相信从事前端开发人员还是对于html,css,javascript,Browser等等有一定认识了解的。但是了解的程度如何呢? 知道含义?简单/熟练使用?深入研究?

请大家试着回答我下面几个问题:

  1. 页面编写是否更多还停留在 div 套 div ?样式编写更多还是宽,高,定位?
  2. JavaScript 是否深入了解过? javascript 为什么是单线程呢?(设计初衷?受限原因?)
  3. JavaScript 在 Browser (浏览器)中如何运行的? 如何编译的?( 预编译?即时编译? )
  4. 在前端领域内自己是否有专注的一个方向?或者说是找工作的杀手锏?
试着解答过后或许结果并不是那么理想,结果如何没有太大关系,个人认为有问题不可怕,及时发现问题就是好的结果。对于每个人来说都不是万能的,是需要时刻学习,时刻进步的。

首先这边 1,2,3 点本篇不展开讲解,网上资料很多可以自行解决有相关具体疑惑地方的话可以留言, (主要前面都是铺垫- -,),咱们直接进入今天的重点,前端领域大家是否有选择一个方向进行深入研究(或者说是找工作的杀手锏)?

这道问题的答案个人觉得深度比广度更容易体现价值。如果因为某些意外大家还没有确定选择方向(那是最好的,哈哈我的机会来了)那么可以认真往下看,说不准本门课程会激发了你的斗志,继而选择了之后深耕的领域,成为领域专家,成为找工作的一个杀手锏。

什么是数据可视化

数据可视化是将数据转化成为交互的图形或图像等,以视觉感受的方式表达,增强人的认知能力,达到发现、解释、分析、探索、决策和学习。

数据可视化主要旨在借助于图形化⼿段,清晰有效地传达与沟通信息。

前端中数据可视化

首先日常开发中越来越多的可视化需求,例如静态类图表如:柱状图,折线图;交互式图表如:网络分析图,智慧社区等等。很多大厂进行了岗位划分,可视化工程师逐渐分离出来(越来越多的重视,导致很多公司投入专门团队研发可视化方向。。。所以前景是一片希望,光明。) 但是从实际出发更多的人研发是通过现成的可视化库去实现自己的需求,这边举几个例子:

  1. D3.js
  2. echarts.js
  3. three.js
  4. Chart.js
  5. cytoscape.js
  6. sigma.js
  7. AntV(G2 G6等)
  8. Go.js
  9. …其他

首先说明本人这边所举框架都是各有优势,例举无排名先后哈,有幸这些技术本人或多或少都有相关技术调研及使用。还是要从业务需求业务场景来考虑到底使用哪一种可视化库。比如D3.js有丰富的动画,交互式图表(事件),图算法;echarts.js 丰富的图表类型,绚丽的特效,支持多渲染引擎等等。

最后说一下本人的一点看法,市面上的可视化库架构设计出发角度更多是抽象化的功能,满足大众化的需求。个人认为好的可视化一定要有”灵魂”,它应该通过可视化完备交互,探索式分析的方式以及背后强大的算力能帮助用户更快更准提取有效价值;如何更好体现业务价值,从交互 算法底层是需要深入研究,自研往往是必经之路。(P:自研此处指并非完全从零实现一个可视化库,可以在现有库基础进行拓展加入业务定制化,比如业务型算法)

如何深入可视化

先来了解一下可视化基础技术架构,基础包含需要:
  1. 渲染层负责可视化图形图像生成相关 API 研发,比如:绘制圆,三角形等
  2. 算法层负责可视化图形图像生成相关算法,比如:布局算法 绘制元素坐标计算如何分布等
  3. 数据层负责数据相关操作,比如:数据增删改查以及数据与视图进行一致性保证等
  4. 其他层例如通信层 工具层等
其次大家都知道很多框架渲染引擎内部是canvas / svg / webgl 实现的,内部到底如何实现? 那么接下来对于渲染层拿canvas举例进行探讨:

图图1.png

比方说实现上方这个可视化图表效果,从canvas绘制层来说,需要提供俩个绘制 API :

  1. 绘制圆形元素
  2. 绘制连线元素
在开始绘制之前

图图2.png

绘制圆形

图图3.png

绘制曲线

图图4.png

以上就是所需要提供的绘制层 API ,后续需要结合算法层比如通过 layout (布局算法)计算节点分布坐标计算、通过节点出入度和业务规则计算节点大小等进行绘制渲染,就可以实现上面美观的可视化。

最后

是不是很有意思呢?
如果想了解学习更多可以看我最新录制的课程

课程链接:https://ke.sifou.com/course/1...

image

课程大纲介绍:

为什么要学这门课?
  • 前端新机遇:大数据可视化
  • 前端开发中的图形学
基础篇:像素级操作大师 Canvas
  • 重新认识Canvas
  • Canvas的优势及特性详解
  • Canvas形状绘制:文本&样式&图片
  • Canvas动效设计与实现
  • Canvas用户交互设计与实现
进阶篇:从零研发关系可视化组件
  • 可视化组件架构设计
  • 编写关系类绘制组件
  • 编写关系类算法(FR)
实战篇:热门可视化库实战
  • d3 入门
  • d3 实战:tree 层级图
  • d3 实战:bar 图表
  • echarts 入门
  • echarts 实战:sankey 图
实战篇:研发关系可视化分析平台
  • 架构设计说明
  • 数据采集清洗
  • 消息机制学习
  • 事件交互学习
  • 项目代码实现
查看原文

赞 7 收藏 5 评论 1

思否编程 发布了文章 · 2020-12-24

彻底搞懂Python 中的 import 与 from import

以下文章来源&作者:青南(谢乾坤)

图片

摄影:产品经理;kingname 的第一套乐高

你好,我是谢乾坤,前网易高级数据挖掘工程师。现任微软最有价值专家(Python 方向),有6年 Python 开发经验,善于解决各种业务场景下的棘手问题,进一步提升代码质量。

对不少 Python 初学者来说,Python 导入其他模块的方式让他们很难理解。什么时候用import xxx?什么时候用from xxx import yyy?什么时候用from xxx.yyy import zzz?什么时候用from xxx import *

这篇文章,我们来彻底搞懂这个问题。

系统自带的模块


以正则表达式模块为例,我们经常这样写代码:

import re
target = 'abc1234xyz'
re.search('(d+)', target)

但有时候,你可能会看到某些人这样写代码:

from re import search
target = 'abc1234xyz'
search('(d+)', target)

那么这两种导入方式有什么区别呢?

我们分别使用type函数来看看他们的类型:

>>> import re
>>> type(re)
<class 'module'>
>>> from re import search
>>> type(search)
<class 'function'>

如下图所示:

图片

可以看到,直接使用import re导入的re它是一个module类,也就是模块。我们把它成为正则表达式模块。而当我们from re import search时,这个search是一个function类,我们称呼它为search 函数

一个模块里面可以包含多个函数。

如果在你的代码里面,你已经确定只使用search函数,不会再使用正则表达式里面的其他函数了,那么你使用两种方法都可以,没什么区别。

但是,如果你要使用正则表达式下面的多个函数,或者是一些常量,那么用第一种方案会更加简洁清晰。

例如:

import re
re.search('c(.*?)x', flags=re.S)
re.sub('[a-zA-Z0-9]', '***', target, flags=re.I)

在这个例子中,你分别使用了re.searchre.subre.Sre.I。后两者是常量,用于忽略换行符和大小写。

但是,如果你使用from re import search, sub, S, I来写代码,那么代码就会变成这样:

import re
search('c(.*?)x', flags=S)
sub('[a-zA-Z0-9]', '***', target, flags=I)

看起来虽然简洁了,但是,一旦你的代码行数多了以后,你很容易忘记SI这两个变量是什么东西。而且我们自己定义的函数,也很有可能取名为sub或者search,从而覆盖正则表达式模块下面的这两个同名函数。这就会导致很多难以觉察的潜在 bug。

再举一个例子。Python 的 datetime模块,我们可以直接import datetime,此时我们导入的是一个datetime模块,如下图所示:

图片

但是如果你写为from datetime import datetime,那么你导入的datetime是一个type类:

图片

因为这种方式导入的datetime,它就是Python 中的一种类型,用于表示包含日期和时间的数据。

这两种导入方式导入的datetime,虽然名字一样,但是他们的意义完全不一样,请大家观察下面两种写法:

import datetime
now = datetime.datetime.now()
one_hour_ago = now - datetime.timedelta(hours=1)
from datetime import datetime, timedelta
now = datetime.now()
one_hour_ago = now - timedelta(hours=1)

第二种写法看似简单,但实则改动起来却更为麻烦。例如我还需要增加一个变量today用于记录今日的日期。

对于第一段代码,我们只需要增加一行即可:

today = datetime.date.today()

但对于第二行来说,我们需要首先修改导入部分的代码:

from datetime import datetime, timedelta, date

然后才能改代码:today = date.today()

这样一来你就要修改两个地方,反倒增加了负担。

第三方库


在使用某些第三方库的代码里面,我们会看到类似这样的写法:

 from lxml.html import fromstring
 
 selector = fromstring(HTML)

但是我们还可以写为:

from lxml import html
selector = html.fromstring(HTML)

但是,下面这种写法会导致报错:

import lxml
selector = lxml.html.fromstring(HTML)

那么这里的lxml.html又是什么东西呢?

这种情况多常见于一些特别大型的第三方库中,这种库能处理多种类型的数据。例如lxml它既能处理xml的数据,又能处理html的数据,于是这种库会划分子模块,lxml.html模块专门负责html相关的数据。

自己来实现多种导入方法


我们现在自己来写代码,实现这多种导入方法。

我们创建一个文件夹DocParser,在里面分别创建两个文件main.pyutil.py,他们的内容如下:

util.py文件:

def write():
    print('write 函数被调用!')

main.py文件:

import util
util.write()

运行效果如下图所示:

image.png

现在我们把main.py的导入方式修改一下:

from util import write
write()

依然正常运行,如下图所示
image.png

 当两个文件在同一个文件夹下面,并且该文件夹里面没有__init__.py 文件时,两种导入方式等价。

现在,我们来创建一个文件夹microsoft,里面再添加一个文件parse.py

def read():
    print('我是 microsoft 文件夹下面的 parse.py 中的 read函数')

如下图所示:

image.png

此时我们在 main.py中对它进行调用:

parse.read()

运行效果如下图所示:

image.png

我们也可以用另一种方法:

from microsoft.parse import read
read()

运行效果如下图所示:
image.png

但是,你不能直接导入microsoft,如下图所示:

image.png


你只能导入一个模块或者导入一个函数或者类,你不能导入一个文件夹

无论你使用的是import xxx还是from xxx.yyy.zzz.www import qqq,你导入进来的东西,要不就是一个模块(对应到.py 文件的文件名),或者是某个.py 文件中的函数名、类名、变量名。

无论是import xxx还是from xxx import yyy,你导入进来的都不能是一个文件夹的名字。

可能有这样一种情况,就是某个函数名与文件的名字相同,例如:

microsoft文件夹里面有一个microsoft.py文件,这个文件里面有一个函数叫做microsoft,那么你的代码可以写为:

from microsoft import microsoft`
microsoft.microsoft()

但请注意分辨,这里你导入的还是模块,只不过microsoft.py文件名与它所在的文件夹名恰好相同而已。

总结


无论是使用import还是from import,第一个要求是代码能够正常运行,其次,根据代码维护性,团队编码风格来确定选择哪一种方案。

如果我们只会使用到某个模块下面的一个函数(或者常量、类)并且名字不会产生混淆,可识别性高,那么from 模块名 import 函数名这没有什么问题。

如果我们会用到一个模块下面的多个函数,或者是我们将要使用的函数名、常量名、类名可能会让人产生混淆(例如 re.S、re.I),那么这种情况下,import 模块名然后再 模块名.xxx来调用会让代码更加清晰,更好维护。

但无论什么情况下,都禁止使用from xxx import *这种写法,它会给你带来无穷无尽的噩梦。

更多内容


Python 开发中的坑不在少数。不仅会严重破坏代码的稳定性,还会影响项目代码开发效率,自身的职业发展甚至是工作状态。

其实,我们并不是不想解决问题、并不是甘于编写所谓“漏洞百出”的代码。只是不知道问题出在哪里、为什么会出现、应该怎样修改。

多年的业务开发,我详尽记录了多个真实发生的错误、坑点,并提炼出 42 章节的《Python 业务开发常见错误案例集》视频课程。

错误坑点主要分为代码编写、开发思想两类。

点击链接,查看视频课详情:https://ke.sifou.com/course/1...
image

课程学习导图如下:https://ke.sifou.com/course/1...
image

查看原文

赞 9 收藏 4 评论 0

思否编程 发布了文章 · 2020-12-22

挑战月薪30K | 前端性能优化的12 条建议(干货收藏)

作者:九思

你好,我是九思,来自腾讯前端技术部,擅长前端监控、工程化相关技术。此篇文章将围绕前端性能优化中监控问题展开讨论。

首先我们要知道,页面打开快不快,不是在电脑或手机上的打开速度说了算,也不是测试同学测试的结果说了算,而是真实用户使用的时候说了算。

那么如何去监控用户真实使用时的页面性能呢?本文将做细致介绍(建议收藏)

前端监控需要注意什么?


首屏

页面上线后,我们最关心用户打开页面的速度,通常就是首屏。

静态资源

页面加载离不开静态资源的加载,包括 js、css、img、video、font 等,在如今盛行 SPA 的场景尤为重要,比如活动页面会有很多图片,我们通常会开发一些模板,由产品/运营同学来配置,而图片多大合适是比较难确定的,网速越来越快,大家对清晰度要求也越来越高,此时就可以通过监测这些图片的加载速度来酌情优化。

API 请求

数据是页面中相当重要的元素,可以说没有数据,你的页面几乎没有使用价值(纯静态除外)。当然这里我们只能粗暴的监控整个请求的总时间,纯前端无法监控各个阶段时间,但这对于线上应用也很重要。

其他测速

实际上线后,不同的应用可能会有不同的测速诉求,比如:视频从加载到播放的时间,此时可以自定义一些测速点,利用之前讲述的打点方式来上报。

如何监控静态资源?


这块其实还是比较简单的,只需要利用 PerformanceResourceTiming 即可,并且它的兼容性极高,可以覆盖到几乎所有场景。

图片

实际监控时,可以分两种场景,如果支持 performanceObserver 可以实时监听,否则使用定时器方式,此外需要将此代码放到页面最顶层,否则无法监控到这段代码之前的资源加载。

 const typeList = \['script', 'link', 'img'\]; //   
 const staticTime = {};  
 const dealTime = (entries) => {  
 for (let i = 0, l = entries.length; i < l; i++) {  
 const entry = entries\[i\];  
 if (typeList.indexOf(entry.initiatorType) !== -1) {  
 staticTime\[entry.name\] = entry.connectEnd - entry.connectStart;  
 }  
 }  
 }  
 if (typeof window.PerformanceObserver === 'function') {   
 const observer = new window.PerformanceObserver((list) => {  
 dealTime(list.getEntries());  
 });  
 observer.observe({ entryTypes: \['resource'\] });  
 } else {  
 setInterval(() => {  
 const allEntries = performance.getEntriesByType('resource');  
 const entries = allEntries.slice(allEntries.length);  
 dealTime(entries);  
 }, 5000);  
 }

entry 部分数值

connectEnd: 32.63499999593478

connectStart: 32.63499999593478

decodedBodySize: 160302

domainLookupEnd: 32.63499999593478

domainLookupStart: 32.63499999593478

duration: 37.54000000481028

encodedBodySize: 23876

entryType: "resource"

fetchStart: 32.63499999593478

initiatorType: "link"

name: "https://stackpath.bootstrapcdn.com

nextHopProtocol: "h2"

redirectEnd: 0

redirectStart: 0

requestStart: 44.60999999719206

responseEnd: 70.17500000074506

responseStart: 65.40999999560881

secu reConnectionStart: 32.63499999593478

serverTiming:[]

startTime: 32.63499999593478

transferSize: 23971

workerStart: 0

图片

API 监控


关于 API 的监控,可以采用重写 XHR 或者 fetch,这样可以适用任何的框架、请求库。时间计算则是通过打点的方式,如果只是固定项目监控,也可以直接采用打点的方式。如果采用重写的方式,不仅可以监控请求的时长,还可以监控请求的成功失败率。

打点最简单的方式:

const startTime = Date.now();  
fn() // 假设这里是同步执行  
const timeCycle = Date.now() - startTime; // fn的执行耗时

除了以上这几点,前端监控的实操中我们还应该考虑到上报、限流以及如何处理这些性能数据。

点击链接查看详情:https://ke.sifou.com/course/1...
图片

上报


发送请求

发送请求我们很容易想到适用 fetch / XHR,当然也可以使用自动发起请求的 HTML 标签,比如 script、link、img。上报数据虽然可以拿来分析页面的真实运行数据,但有一点要注意的是:不能影响当前页面的运行或最小程度的影响。

是否可以直接用 fetch/XHR 呢?答案是否定的,因为上报的域名和页面的域名基本是不同的,所以这里需要可以前端跨域的方式。

说到跨域,浏览器的 src 属性标签基本都可以,到底用哪个呢?原则上要适用对页面影响最小的那个,诸如 Script、link 这些标签之前有讲述,他们都会对页面的运行造成影响。

img 变成了较为合适的方式,构造图片打点不仅不用插入DOM,只要在 JSnewImage 对象就能发起请求,而且还没有阻塞问题,在没有js的浏览器环境中也能通过 img 标签正常打点,这是其他类型的资源请求所做不到的。

在所有图片中1px x 1px 大小,gif 体积最小,相较 BMP/PNG,可以节约41%/35%的网络资源,所以适用 gif 相对是最佳选择。

限流

页面的性能数据,每次访问都会有,如果你的项目 pv 有一定量级,那么处理起来就会相当耗费资源,而且这些数据我们最终是求平均值或者分位值,所以没必要全量上报。那么我们可以在上报前做一些限流处理。

更多内容


除了以上这几点,前端监控的实操中我们还应该考虑到如何处理这些性能数据,主要有取中位数、平均值、分位数等做法,由于篇幅有限此处不做详细介绍。

最后,如果这篇文章给你带来些许有价值的理解,欢迎点赞、分享,更多内容可翻阅我的付费专栏《前端性能优化12问》。

点击链接查看详情:https://ke.sifou.com/course/1...
图片

查看原文

赞 46 收藏 31 评论 0

认证与成就

  • SegmentFault 讲师
  • 获得 279 次点赞
  • 获得 3 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 3 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2019-12-03
个人主页被 25.6k 人浏览