思否编程

思否编程 查看完整档案

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

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

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

添加编程小姐姐微信:bobonadia

个人动态

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

Kubernetes 难上手?试试这些工具!

你好,我是FamZ,曾就职字节跳动公司,担任高级系统性能工程师,擅长:内核、虚拟化、Docker、Kubernetes等

相信不少同学对于 Kubernetes 已经摩拳擦掌,作为当下最流行的服务运维平台,这个盛名之下的庞大软件到底怎么玩转?

作为一个功能丰富、组件众多的“云原生操作系统”,安装和配置Kubernetes 的复杂性的确容易让人望而却步。不过,Kubernetes 社区经过几年的快速发展,已经出现了不少颇为易用的安装、部署工具,能够帮助初学者和新用户用最简单的步骤上手 K8s。

接下来跟我一起尝试用下面几个非常易用的工具,开始自己的 Kubernetes 学习之旅吧~

MicroK8s

MicroK8s 是由Ubuntu推出的基于snap的包。在最新的 Ubuntu 系统下(20.04以上),可以直接使用 snap 命令快速安装一个本地 Kubernetes 集群。

在 shell 中执行如下命令:

$ sudo snap install --classic microk8s

(如果系统没有 snap 命令,可以通过 apt-get install snap 来安装)

MicroK8s安装完成以后,通过 sudo microk8s kubectl 命令来访问集群:

$ sudo microk8s kubectl get node 
NAME               STATUS     ROLES    AGE   VERSION
ip-172-44-255-31   NotReady   <none>   65s   v1.20.2-34+350770ed07a558

MicroK8s 还集成了很多插件,比如 storage插件也可以通过 microk8s 命令来管理。例如:

$ sudo microk8s enable storage ingress

如果想把多个节点加入同一个 Kubernetes 集群,可以使用sudo microk8s add-node 命令,然后根据提示进行操作。

K3S

K3S 是 Rancher 推出的一个高集成度的 Kubernetes 发行版,所有的组件都被打包在一个可执行文件中,并且进行了轻量化。

K3S程序可以在这里下载:

https://github.com/rancher/k3s/releases/latest

把 K3S 文件下载到 /usr/local/bin 并且设为可执行以后,就可以用一个命令启动集群服务:

$ sudo k3s server

访问集群同样是通过 K3S 命令:

$ sudo k3s kubectl get node

如果要把多个主机加入一个集群,可以在另外的节点上执行:

$ sudo k3s agent –server https://$SERVER:6443 –token $TOKEN

其中 $SERVER 和 $TOKEN 要匹配第一台主机的地址和 /var/lib/rancher/k3s/server/node-token 文件内的令牌。

image.png

链接:https://ke.sifou.com/course/1...
(小编插播:课程上新福利,仅需59元哟~)

RKE

RKE的全称是 Rancher Kubernetes Engine,也是由 Rancher开发和维护的Kubernetes发行版。跟偏重边缘计算场景的 K3S 相比,RKE 更多面向传统的数据中心生产环境,偏重集群化部署,且可定制性更强。

要安装一个 RKE 的集群,可以从这里下载 RKE 程序:

https://github.com/rancher/rke/releases

然后使用 rke config --name cluster.yml 创建一个新的集群部署配置。

编辑 cluster.yml 文件,填充集群的主机列表和访问方式等,同时还可以定制集群的初始化配置。

配置文件的一个片段如下:

image.png

然后执行 rke up 命令,就会开始安装。注意部署 RKE 的节点需要预先安装Docker。

完成以后,当前目录下出现 kube_config_cluster.yml 文件,即可通过 kubectl命令来访问集群:

$ kubectl –kubeconfig kube_config_cluster.yml get node

KIND

Kind 是 Kubernetes-in-Docker 的缩写。在安装有 Docker 的主机上创建一个测试用的多节点Kubernetes集群非常容易,而且由于整个集群都在 Docker 的容器环境中运行,不会对主机环境和其它配置造成过多干扰。

kind 命令可以从这里下载:

https://kind.sigs.k8s.io/

保存到 /usr/local/bin 以后,直接执行 kind create cluster 就可以创建一个集群:

image.png

如果你想尝试多节点的集群,也可以:

$ cat > kind.config <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
# One control plane node and three "workers".
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
EOF
$ kind create cluster --config kind.config

命令完成后,系统中会出现几个新的 Docker 容器。并且 $HOME/.kube/config 文件会自动更新,因而直接运行 kubectl get node 就可以访问 kind 集群了。

有了这些高质量的部署和实验工具,学习 Kubernetes 将会事半功倍。更多关于Kubernetes的干货内容,可以关注我和思否编程联合出品的课程《Kubernetes详解与实践:基础篇

Bon courage!

戳链接:https://ke.sifou.com/course/1...
原价¥299,立省¥240
到手价仅¥59!

查看原文

赞 2 收藏 0 评论 0

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

快速上手Grape:为什么每个人都应该有一套自己的脚手架?

作者:Run,总架构师
工作经验 5 年,当前就职行业知名技术公司,担任总架构师职位,擅长前后端技术栈,Ruby、Python、JavaScript 等语言。

内容目录

针对 Grape 框架的改进

深层 expose

你也许知道,expose 可以嵌套。如果传递的是个不带参的块,则会执行嵌套渲染:

class Entities::Article < Grape::Entity
 expose :user do
 expose :name { |article| article.user.name }
 expose :age { |article| article.user.age }
 end
end

如上,会渲染一个如下的数据结构:

{
 "user": {
 "name": "Jim",
 "age": 18
 }
}

如果此时传入 deep: true,则嵌套层绑定的 instance 就不一样了。下面的例子与上面的例子展示了同样的效果:

class Entities::Article < Grape::Entity
 expose :user, deep: true do
 expose :name
 expose :age
 end
end

接口返回值声明

status 用于声明接口的返回值(successfailentity 是特殊情况下的别名)。它有如下几种基本的调用形式:

status 200 do
 expose :article, using: Entities::Article
end
​
status 200, '返回文章数据' do
 expose :article, using: Entities::Article
end
​
status 400, '请求参数有误' do
 expose :code, desc: '错误码'
 expose :message, desc: '错误消息'
end
​
success '请求成功' do
 expose :article, using: Entities::Article
end
​
fail '请求失败' do
 expose :code, desc: '错误码'
 expose :message, desc: '错误消息'
end
​
entity do
 expose :article, using: Entities::Article
end

上述声明主要起两个作用:

  1. 在接口逻辑中调用 present 方法不用显示地指定 Entity 类型,它是自动解析的。

    以前,你必须这样调用:

    present :article, article, with: Entities::Article

    现在,只用这样:

    present :article, article

    因为在 status 声明中它已经知道如何渲染 article 实体了。

  2. status 声明可对应生成文档。

参数、返回值一体化

Grape::Entity 新加一个 to_params 方法,使得你可以在参数声明中重复利用:

params do
 requires :article, type: Hash do
 optional :all, using: Entities::Article.to_params
 end
end

它比 Grape::Entity.documentation 更好用,做了如下改进:

  1. type 可以写成字符串:

      expose :foo, documentation: { type: 'string' }
  2. 可混用额外参数,如同时指定 param_type 参数:

      expose :foo, documentation: { param_type: 'body' }
  3. 合理处理了 is_array

     expose :bar, documentation: { type: String, is_array: true }

针对测试的改进

现在可以用编程 style 的方式测试接口的返回值了,不需要再测试诸如 JSON 字符串、XML 文本之类的。如果像下面这样实现接口:

present :article, article

就可以像下面这样测试:

get '/article/1'
assert_equal 200, last_response.status
assert_equal articles(:one), presents(:article)

注意,这个功能不是实现在框架中的,需要克隆脚手架项目:

git clone https://github.com/run27017/grape-app-demo.git

新手如何上手

如果你是完全的新手,建议先从熟悉 Grape 框架开始。我建议您阅读我仓库下的文档。在您熟悉了 Grape 框架以后,再阅读以上我对 Grape 框架改进的部分。关于整个框架的设计理念,可阅读后文。

项目上手就从我提供的脚手架项目开始,所有功能都集成进来了:

git clone https://github.com/run27017/grape-app-demo.git

理念

面向文档的开发

当今环境下,有许多的开发范式供后端开发者选择,例如_测试驱动开发_、_行为驱动开发_、_敏捷软件开发_等等。与之相对的,我提出了一个新的想法,我将其称为_面向文档的开发_。

写 API 项目的同时是要准备文档的。我不知道大家是如何准备文档的,但往往都逃不出一个怪圈:同一个接口,我的实现要写一份,我的文档也要同时写一份。我常常在想,为什么我在写接口的同时不能将文档同步地完成呢?换个角度想,接口文档的契约精神为何不能自动地成为实现的一部分?如果,我能发明一个 DSL,在编写文档的同时就能够制约接口的行为,那不正是我想要的吗?

说干就干!

我发现 Grape 框架就已经提供了类似的 DSL 了。例如你在制定参数时可以像这样:

params do
 requires :user, type: Hash do
 requires :name, type: String, desc: '用户的姓名'
 requires :age, type: Integer, desc: '用户的年龄'
 end
end

上面的代码就可以对参数进行制约,限制参数为 nameage 两个字段,并分别限制它们的类型为 StringInteger. 与此同时,一个名为 grape-swagger 的库可以将 params 的宏定义渲染成 Swagger 文档的一部分。完美,文档和实现在这里结合了。

另外,Grape 框架提供了 desc 宏,它是一个纯文档的声明供第三方库读取,不会对接口行为产生任何影响。

desc '创建新用户' do
 tags 'users'
 entity Entities::User
end

但是,毕竟 Grape 框架不是完全的面向文档的开发框架,它有很多重要的使命,所以它和文档的无缝衔接也就仅限于此了。你能看到,params 宏是个完美结合的范例,desc 宏很可惜只与文档渲染有关,然后就别无其他了。

鉴于 Grape 框架是个开源框架,修改它以添加几个小零件还是很简易的一件事。我用了几天的时间添加了一个 status 宏,可以用它来声明返回值:

status 200 do
  expose :user, deep: true do
    expose :id, documentation: { type: Integer, desc: '用户的 id' }
    expose :name, documentation: { type: String, desc: '用户的姓名' }
    expose :age, documentation: { type: Integer, desc: '用户的年龄' }
  end
end

上述声明主要起两个作用:

  1. 在接口逻辑中调用 present 方法不用显示地指定 Entity 类型,它是自动解析的。

    以前,你必须这样调用:

    present :user, user, with: Entities::User

    现在,只用这样:

    present :user, user

    因为在 status 声明中它已经知道如何渲染 user 实体了。

  2. grape-swagger 库可以解析 status 宏生成文档。

一切还只是冰山一角。

你真的不需要 Controller 测试吗?

有关接口的单元测试,有两个观点争论不休:接口测试应该是针对 Integration 测试还是 Controller 测试?Integration 测试像是一个黑匣子,开发者调用接口,然后针对接口返回的视图进行测试。而 Controller 测试也会一样地调用接口,但会测到内部的状态。

通过下面的两个案例直观地感受一下 Controller 测试和 Integration 测试在 Rails 框架中的不同写法。

在早期的 Rails 版本中,是有 Controller 测试的:

class ArticlesControllerTest < ActionController::TestCase
  test "should get index" do
    get :index
    assert_response :success
    assert_equal users(:one, :two, :three), assigns(:articles)
  end
end

Rails 5 以后,更推荐 Integration 测试:

class ArticlesControllerTest < ActionDispatch::IntegrationTest
 test "should get index" do
 get articles_url
 assert_response :success
 end
end

注意到 Integration 测试中是没有对应的 assert_equal 语句的,因为它比较难写。如果视图返回的是 JSON 数据,可以尝试用下面的等效写法:

assert_equal users(:one, :two, :three).as_json, JSON.parse(last_response.body)

但是测试视图的代码及其依赖视图的变化,也会经常性的失效,上面只是尝试性的一种写法而已。

我不想在这里探讨 Controller 测试和 Integration 测试究竟孰优孰劣的问题,尽管你可能已经从字里行间察觉到我的倾向性。关于这个话题能够从 2012 年讨论到 2020 年,不信你可以看这个帖子。我可不想让情况变得更糟。很多次我在想,那些反对 Controller 测试的人可能仅仅把 Controller 的实例变量看成是其内部状态而已,而没有意识到它也是 Controller 与 Template 之间的契约。这不怪他们,因为用传递实例变量的方式定义契约确实不够优雅。

好在我做了一些简单的工作,让其在 Grape 框架内可以更优雅地测试接口的返回。你只需要在逻辑接口中使用 present 方法指定渲染数据:

present :users, users

然后就可以在测试用例中结合特殊的 presents 方法测试它:

assert_equal users(:one, :two, :three), presents(:users)

assigns 很像,但是它更舒服不是么?

写在最后

这就是我对 Grape 框架的改造过程,已经开始并将持续下去。我的改造理念无外乎两个想法:更好的文档结合和更好的测试。而事实上,只需要一点点工作,确实就可以起作用了。

如果你也想用到我所改造的 Grape 框架,直接克隆我的脚手架就好了:

git clone https://github.com/run27017/g...

脚手架中使用的是我 Fork 后的框架集,它们是:

点击它们的链接看一看吧,也许你也能成为开源世界的贡献者呢。

推荐

如果想了解学习更多可以看我最新录制的课程

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

设计这门课的初衷
  • 当前 Web 开发的主流模式:前后端分离
  • Web API 开发,没有必要五花八门,应采用最佳实践
  • 将自己多年的实践经验总结并分享
这门课在讲什么?
  • 遵循标准:最小惊讶原则
  • 接口的完备性:输入和输出、鉴权、错误处理等
  • 与框架整合
为什么每个人都应该有一套自己的脚手架?
  1. 框架只是通用模版的提供者,并没有安排具体的解决方案
  2. 框架并没有细化到最佳实践
查看原文

赞 6 收藏 2 评论 0

思否编程 赞了文章 · 1月27日

Objective-C 之父 Brad J. Cox 去世,他推动了苹果软件生态的发展

Objective-C 之父 Brad J. Cox 去世,他推动了苹果软件生态的发展

据外媒报道,编程语言 Objective-C 之父 Brad J. Cox 博士已于近日在其家中逝世,享年 77 岁。

Objective-C 是一种通用、高级、面向对象的编程语言,可以在现存 C 编译器基础上实现,而不需要编写一个全新的编译器。史蒂夫·乔布斯曾在苹果开发 NeXTSTEP 操作系统时,使用了Objective-C。现在,Objective-C 仍是 OS X 和 iOS 操作系统、及与其相关的 API、Cocoa 和 Cocoa Touch 的主要编程语言。

苹果生态开发者最熟悉的编程语言之一

Objective-C 名称的由来是:在 C 语言主体上加入面向对象的特性。任何 C 语言程序不经修改就可以直接通过 Objective-C 编译器,在 Objective-C 中使用 C 语言代码也是完全合法的。它扩展了标准的 ANSI C 编程语言,将 Smalltalk 式的消息传递机制加入到 ANSI C 中。目前主要支持的编译器有 GCC 和 Clang(采用LLVM 作为后端)。

当年,史蒂夫·乔布斯为其新操作系统 NEXTSTEP 授予了 Objective-C 语言许可。Objective-C 成为了苹果生态开发者最熟悉的编程语言之一。
Objective-C 可以在现存 C 编译器基础上实现,而不需要编写一个全新的编译器,使得它能利用大量现存的C 代码、库、工具和编程思想等资源。

但随着编程语言的不断演进,Objective-C 的缺点也逐渐暴露出来,比如不支持命名空间;不支持运算符重载;不支持多重继承;使用动态运行时类型,所有的方法都是函数点用,很多编译时的优化方法都用不到等。因此,近年来,苹果一直想让开发者放弃 Objective-C,转向 Swift。在开发语言排行榜 TIOBE 榜单中,Objective-C 的流行程度指数一路下滑,替代者 Swift 的位次逐渐上升。

早在 2015 年,就有人预言 Objective-C 将在五年内被 Swift 取代。但由于代码规模庞大,Objective-C 短时间内无法被彻底取代。

职业生涯精彩而圆满,著作被翻译成 10 余种语言

image.png

1944 年 5 月 2 日,Brad J. Cox 出生于佐治亚州的本宁堡,他在南卡罗来纳州一家奶牛场长大。Brad J. Cox 从小就发现了自己对科学的兴趣,他曾获得弗曼大学有机化学与数学理学学士学位和博士学位,还拿到了芝加哥大学数学生物系的博士学位,并从事神经网络早期形式的研究。

不过,Brad J. Cox 很快发现自己对计算机更感兴趣,并在国际电话电报公司(ITT)找到了一份工作,后来加入了 Schlumbeger-Doll Research Labs,最终创办了自己的企业 Productivity Products International(PPI),后称 Stepstone。在Brad Cox 的第一个知名软件项目中,他编写了 PDP-8 程序来模拟神经元簇。在进入软件行业之前,他曾在美国国立卫生研究院和伍兹霍尔海洋研究所工作。

Brad Cox 的在线课程“Taming the Electronic Frontier”获得了 1998 年的 Paul Allen 远程教育奖。1991年,Brad Cox 出版了他的《Object Oriented Programming: an Evolutionary Approach》一书,并于 1996 年出版了《Superdistribution: Objects as Property on the Electronic Frontier》,该书被翻译成 10 余种不同的语言。

举世闻名的计算机科学家逝世

生活中,Brad J. Cox 爱好音乐和潜水,早年间他还是一个乐队的成员。在一次潜水旅行中,Brad J. Cox 与一对德国夫妇进行了交谈,巧合的是,这位旅行者也是一个程序员。在交谈中,对方问到了 Brad J. Cox 的职业,并询问他具体是做什么的,Brad J. Cox 回答说,他写了 Objective-C。对方非常惊讶,并说:“不,Objective-C 是 Brad J. Cox 写的。”于是,Brad J. Cox  正式向这位潜水伙伴介绍了自己。

在 Brad J. Cox 的生活中,这样的事屡屡发生。在悼念他的帖子中,还有人写道:“Brad Cox 从不宣扬自己是一个举世闻名的计算机科学家,而是和我们这些普通码农一起肩并肩敲代码。他是一个正直、受人尊敬的人。”

讣告原文:https://www.legacy.com/us/obituaries/scnow/name/brad-cox-obituary?pid=197454225

参考链接:https://blog.wongcw.com/2021/01/24/
segmentfault 公众号

查看原文

赞 3 收藏 0 评论 1

思否编程 赞了文章 · 1月27日

官宣了!Apache ECharts 毕业成为 Apache 软件基金会顶级项目!

2021 年 1 月 26 日,德克萨斯州威明顿市 Apache Blog 原文

Apache 软件基金会(ASF)是 350 多个开源项目和计划的全志愿开发者、管理者和孵化者,今天宣布 Apache® ECharts™成为顶级项目(TLP)。

Apache ECharts 是一个直观、可交互、强大的可视化图表库,非常适合用来作为商业级的图表演示。该项目在 2013 年起源于百度,2018 年 1 月进入 Apache 孵化器。

“我们在 Apache 软件基金会孵化 ECharts 是一个明智的决定,”Apache ECharts VP 羡辙说,“通过学习并采纳 Apache Way,我们的社区更加健康和多样化,这改善了 ECharts,使其成为可视化专业人士和爱好者更具吸引力和竞争力的选择。”

Apache ECharts 用 JavaScript 编写,基于支持 Canvas 和 SVG 的 ZRender 渲染引擎,提供了一系列动态的、高度可定制的图表类型,包括线图、柱图、散点图、饼图、雷达图、K 线图、仪表图、漏斗图、热力图等。功能包括:

  • 超过 20 种图表类型以及自定义图表
  • 多维度数据分析和处理
  • 开箱即用的交互组件
  • 多设备的响应式设计
  • 大数据性能优化
  • 服务器端渲染
  • 通过渐进式渲染,实现千万级数据的实时交互

以及各种扩展应用:

  • 3D 可视化和其他丰富的特效
  • Python、R、Julia 和其他语言封装了基于 ECharts 的可视化库
  • 适配包括微信小程序、百度智能程序在内的多种平台

可以在 https://echarts.apache.org/ex... 找到 ECharts 的数据可视化例子。

该项目最近发布了最新版本 ECharts 5,它提供了千万数据的渲染能力,并支持符合 W3C 的 Web Accessibility Initiative Accessible Rich Internet Applications Suite(WAI-ARIA)标准的可访问性要求。

image

在 ECharts 核心功能的基础上,ECharts 5 通过在动画叙事、优化的可视化设计、交互体验、性能提升、开发体验、国际化、可访问性等方面的 15 项新功能和改进,让开发者更容易讲述数据背后的故事。

阿里巴巴、亚马逊、百度、GitLab、英特尔和腾讯等公司,以及 Apache Superset 数据可视化软件等解决方案使用了 Apache ECharts 来开发他们的可视化产品。该项目的受欢迎程度正在持续增长,截至目前,GitHub 上的 Star 数量超过 44000,npm 上的周下载量也超过 250000 次。

“我们今天生活的世界是由软件和数据驱动的,”GitHub 的首席运营官 Erica Brescia 说。“有了 Apache ECharts,全世界的开发者都可以访问一个强大的、免费的、开源的数据可视化库。我们很高兴看到该项目在 GitHub 上蓬勃发展。恭喜 Apache ECharts 毕业成为 Apache 软件基金会的顶级项目。”

“Apache ECharts 可以帮助可视化专家和数据分析师轻松创建各种各样的可视化,对我们分析和探索数据背后的故事非常有帮助。”可视化学术先锋人物、浙江大学陈为教授说。

“我们很高兴见证 ECharts 在 Apache 孵化器中的愉快过程。”百度高级经理祖明说。“我们的社区与来自许多国家和组织的个人一起成长,他们在错误修复、问题解决和新功能实现方面做出了贡献。”

“当 Apache Superset 社区研究可视化库以重建核心可视化插件时,ECharts 脱颖而出,成为绝对的最佳选择。”Apache Airflow 和 Superset 的最初创建者、Apache Superset VP 的 Maxime Beauchemin 说,“它拥有无与伦比的可视化种类,丰富且可组合的可视化语法、直观且设计良好的 API、灵活且性能卓越的渲染引擎、非常精简的依赖项,以及 ASF 在长期承诺使用一个开源项目时提供的一系列重要保障。”

“通过 Apache 孵化器指导 ECharts 社区是一件很愉快的事情,”ASF 成员、Apache ECharts 孵化导师 Dave Fisher 说,“他们接受了社区主导开发的 Apache 方式,鼓励那些有兴趣帮助改进 ECharts 的人做出贡献,成为其成长社区的一部分。”

“对于 ECharts 社区来说,这是一个激动人心的时刻,”羡辙补充道,“我们正在保持持续的增长,也非常欢迎对此感兴趣的人成为我们的开发者和维护者。”

在“5 分钟了解可视化利器 Apache ECharts”中,你可以了解到更多 ECharts 的功能——这是一个由 Apache ECharts 社区成员创建的新视频。

https://www.bilibili.com/vide...

可用性和监督

Apache ECharts 软件在 Apache License v2.0 下发布,并由一个自选的积极贡献者团队监督。项目管理委员会(PMC)指导项目的日常运作,包括社区开发和产品发布。有关下载、文档和参与 Apache ECharts 的方法,请访问 http://echarts.apache.orghttps://twitter.com/ApacheECh...

关于 Apache 孵化器

Apache 孵化器是希望成为 Apache 软件基金会工作一部分的项目和代码库的主要进入途径。所有来自外部组织的代码捐赠和现有的外部项目都要通过孵化器进入 ASF,以达到以下目的 1)确保所有的捐赠符合 ASF 的法律标准;以及 2)开发新的社区,遵守我们的指导原则。所有新接受的项目都必须进行孵化,直到进一步的审查表明基础设施、通信和决策过程已经稳定下来,与其他成功的 ASF 项目一致。虽然孵化状态不一定反映了代码的完整性或稳定性,但它确实表明该项目尚未得到 ASF 的完全认可。欲了解更多信息,请访问 http://incubator.apache.org/

关于 Apache 软件基金会 (ASF)

Apache 软件基金会(ASF)成立于 1999 年,是世界上最大的开源基金会,管理着 2.27 亿多行代码,并 100% 免费向公众提供价值超过 200 亿美元的软件。ASF 的全志愿者社区从最初的 21 位创始人监督 Apache HTTP 服务器发展到现在的 813 位个人成员和 206 个项目管理委员会,他们通过 ASF 的择优程序,与近 8000 位 Committer 合作,成功地领导了 350 多个 Apache 项目和计划。Apache 软件几乎是每一个终端用户计算设备的组成部分,从笔记本电脑到平板电脑,再到企业的移动设备和关键任务应用。Apache 项目为大部分的互联网提供了动力,管理着 exabytes 的数据,执行着 teraflops 的操作,并在几乎每个行业中存储着数十亿的对象。商业友好和允许的 Apache 许可证 v2 是一个开放源码的行业标准,帮助启动了价值十亿美元的公司,并使全球无数的用户受益。ASF 是美国 501 (c)(3) 非营利性慈善组织,由个人捐款和企业赞助商资助,包括 Aetna、阿里巴巴云计算、亚马逊网络服务、Anonymous、百度、彭博社、Budget Direct、Capital One、Cloudera、Comcast、Didi Chuxing、Facebook、Google、Handshake、华为、IBM、Microsoft、Pineapple Fund、Red Hat、Reprise Software、Target、腾讯、Union Investment、Verizon Media 和 Workday。欲了解更多信息,请访问 http://apache.org/https://twitter.com/TheASF

© Apache 软件基金会。 "Apache"、 "ECharts"、 "Apache ECharts"、 "Airflow"、 "Apache Airflow"、 "Superset"、 "Apache Superset" 和 "ApacheCon" 是 Apache 软件基金会在美国和/或其他国家的注册商标或商标。所有其他品牌和商标都是其各自所有者的财产。

特别提醒:Apache ECharts 5 将于 2021.01.28 20:00 进行线上发布会。届时,将由众多 Apache ECharts PMC 和 Committers 为大家详细介绍 ECharts 5 的新功能,帮助大家快速上手拥有强大叙事能力的 Apache ECharts 5!长按下面的二维码关注直播间~

image

查看原文

赞 24 收藏 0 评论 0

思否编程 发布了文章 · 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 图
实战篇:研发关系可视化分析平台
  • 架构设计说明
  • 数据采集清洗
  • 消息机制学习
  • 事件交互学习
  • 项目代码实现
查看原文

赞 12 收藏 8 评论 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

认证与成就

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

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

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