go语言在爬虫中的应用

随风

go语言有21世纪c语言的美誉,实际也表现出了极好的性质。go语言具有轻量级的协程goroutine,能轻而易举地实现数万并发。并且可以真正多核并行,充分利用cpu。语法明快,使用起来没有臃肿和历史包袱。标准库文档齐全而且极易阅读。

在爬虫领域,人们使用最多的当属python,python有数不清的爬虫库。以至于人们几乎把python等价成了爬虫专用。似乎人工智能和数据科学领域也如此。实际上,无论是人工智能还是爬虫,它们都是一种算法或者说是一种技术手段,使用什么语言其实影响并不大。

什么是爬虫?爬虫违法吗?爬虫用一句话来概括就是the website is the api。爬虫程序利用网络请求或者selium一样的模拟点击自动化测试工具来获取互联网上的海量信息。百度等搜索引擎其实也是这样做的,所以爬虫技术本身其实并不违法。但是造成了网站服务器崩溃以及其它恶劣影响事件则有可能会违法甚至犯罪。

go语言有强大的net库,本身带有cookiejar等组件,来保持会话,还有健壮的并发机制。对于海量信息的获取,go语言能够使用简单的算法就能获取极高的爬虫效率。而不需要像python scrapy 那样使用twisted以及队列模型,这极大的增加了编程的复杂性。至于chanel(管道),go语言更是原生支持。所以go语言在爬虫领域有着十分光明的前景。

go语言缺乏很好的大而全的爬虫框架,但是也有诸多工具,如goquery,colly,chromedv,运用这些工具我们已经足以完成一般的爬虫软件开发。当然纵观go语言领域,大而全的框架其实很少,更多的是轻量级框架如gin。也许是吸取了spring全家桶笨重的教训,即使是springboot,大大简化了配置,但是由于历史包袱原因,至今底层仍需要netty或者tomcat的支持,排错比较麻烦,对新手不那么友好。

爬虫学得好。。。,下面我就不说了,各位还是在尊重法律的基础上畅享爬虫带来的乐趣。

谈谈go语言的关键字

随风

go语言的关键字极其少,充分体现了少就是多的哲学。go一共有多少关键字呢?我在论坛搜索了一波,发现只有25个关键字。

go的25个关键字:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

可以看出这些关键字里面居然连常见的int等类型定义都没有,却添加了内置支持类型map和chan。map的作用不用多说,键值对处理的必备,而chan则是go语言处理协程通讯的基本工具。但是int等类型真的不是关键字吗?我的回答是,那当然,看看下面这段奇怪的代码你就明白了。

代码“居然”正常编译运行了,不过这样的写法估计你离离职也不远了吧。

不得不说go的关键字设计确实有点大胆,只能说佩服佩服。

欢迎关注创万联公众号。

谈谈frp内网穿透

随风

由于ipv6落实的缓慢,不少地方仍然无法使用ipv6。而ipv4的地址早已枯竭,那怎么办呢?人们想到了一种nat技术。但这样一来就造成了人们大部分生活在一张大内网。在大内网里,人们仍然可以正常上网,但对于我们这种有服务器运营需求的人可就麻烦了。没有公网ip意味着无法从外界自由访问,只能供给内网使用,那我们辛辛苦苦写的物联网平台岂不是毫无作用?别急,正所谓山重水复疑无路,柳暗花明又一村,内网穿透技术解决了这个看似无法解决的困局。

内网穿透的工具众多,如花生壳等,但是普遍价格不菲。有些厂家并不良心,高价买回的穿透隧道却只是映射单一协议和单一端口映射的穿透隧道。一但有大量web程序要部署其中的成本堪称天价。我所工作的某实验室也曾经使用过某穿透产品,价格贵而协议单一,端口也单一,稳定性很差,经常掉线。为此我们web人员深有体会,感觉到内网穿透行业巨大的天坑,并决定抛弃这款产品。

我的一个好朋友曾经给我介绍过frp这款软件,这款软件是一个用go语言写的开源软件,能映射众多协议和端口。只需要一台公网服务器和少量配置即可完成服务端搭建。我并不打算在这里介绍搭建方法,因为网上相关资料极多。客户端可以采用openwrt的软路由,这样整个内网的设备都可以方便地穿透出去。在我的极力建议下,实验室的frp和docker配合搭建的云平台终于开始走入正轨,并逐渐显露出frp穿透的巨大优势。

技术是需要冒险的,如果不是这样。试问浩瀚苍穹,人类何能遨游其中?这就是我对实验室frp搭建的总结。最后说个题外话,我们祝贺创万联获得新软著和wonder获得物联网工程师证书,这些小小成果总将汇成大流。

物联网与人工智能短期谁更具市场价值

随风

物联网和人工智能无疑已经成为了工科创新比赛中热点中的热点。挑战杯以及互联网+关于这两者的创新作品多到眼花缭乱,物联网甚至开始有些跟不上创新比赛的要求了,因为有关于物联网的毕设作品都已经到了烂大街的地步。

不过我今天不讨论创新比赛,因为创万联现在已经不是创新比赛团队。我们的目标只有一个,实现市场化。因而市场价值对于我们来说才是最重要的东西。当然市场价值也有长期和短期的,今天我们主要讨论短期的。

进入21世纪以来,科技日新月异,各种科技产品蜂蛹而出。但在我看来智能手机,网购,即使通讯和移动支付都属于互联网革命。本质是互联网技术的深化应用。互联网的宗旨是连接人与人,因而我们当前的时代是信息时代。但大概在2015年左右,物联网由于智能家居的发展,开始由概念走向现实的时候,我们已经可以断定,一个新时代就要到来,物联网革命即将拉开序幕。基于物联网的各种市场应用,在不久的将来一定会大放光彩。但人工智能的短期前景其实并不算太明朗,主要的约束是算力,GPU的价格居高不下,大规模走进日常生活,或者短期内想单纯依靠人工智能构建一个商业帝国我想可能性非常地小。但长期来讲两种技术一定会走向融合,形成aiot技术,届时我们的生活将会翻天覆地,马云口中的数据时代也就会真正到来。

连接万物的物联网主要的硬件基础设施在于通讯技术和嵌入式处理器。软件设施就是物联网平台以及对应的消息中间件。其实目前的工业上的现场总线,以及相当接近物联网的概念,但仍然不是真正的物联网,真正的物联网是打破地域和区域界限的。举个例子,我们可以在美国收到来自江门设备的报警。物联网现在最难克服的问题不是技术,恰恰就是生态以及对应的效益,简单采集数据的物联网毫无意义。

人工智能技术发展最为迅速的就是自然语言处理和视觉,目前主要的实现手段就是深度学习。深度学习中著名的卷积神经网络已经得到了极为广泛的应用,分类识别效果也非常地优秀。但有一点需要注意的是,这里的人工智能都严重地依赖数据集,制作数据集非常耗费时间和精力,数据集是深度学习的灵魂,如果没有优秀的数据集分类和识别效果也就无从谈起,因而想要人工智能大规模投入生活的各个方面,我们首先必须解决数据采集的问题,物联网也正是解决的最好途径。

如此看来,短期内我觉得还是物联网更具大规模市场应用前景。

微服务引领新时代

随风

随着docker等容器技术的流行以及云计算的成熟。微服务作为一种全新的设计思维悄然问世。微服务是soa架构的变种。微服务是一种云原生的架构,其中单个应用程序由许多松散耦合且可独立部署的较小组件或服务组成。微服务的本质是分布式的,不同于传统的大型集中形式架构,微服务每一部分都可独立部署,耦合程度非常低。微服务的诞生标志着程序开发进入了真正的云时代。

讲了一大通概念我自己都很烦,我确实不热衷于炒概念,不过概念有时候也是必须的。它可以清晰地描述事物的本质。微服务,顾名思义在于微和服务。微相对于宏,就是小型的集合体。服务就不用多说了。微服务确实带来了很多好处,例如管理上的以及维护等。但也使得程序整体变得更加复杂了,所以只有大型的或者是分布式的应用又或者是云原生应用才会感受到微服务带来的好处。如果为了微服务而微服务,就我个人感觉而言,还不如直接不用微服务,因为分布式固有的复杂性并不低,需要处理诸如消息注册发现以及服务调用问题,还有部署大量的微服务本身就是一个复杂的学问。

我认识微服务时间不长,但微服务的思维在创万联由来已久。但苦于没有找到合适的工具,直到我认识了Spring Cloud,这一切才发生了改变。Spring Cloud确实给我带来了极大的冲击,一瞬间我感到只有一句话—–太爽了。感谢spring全家桶,你的存在让我这种蹩脚程序员不至于碌碌无为,也可以开发出好玩的应用。

Spring Cloud并不是彻底地重构出一个全新的架构,其实这也是spring家族历来坚守的信条:不重复制造轮子。在spring诞生的十几年,spring确实做到了。它不但打败了强劲的对手ejb,而且开发出了spring boot使得java开发的复杂性断崖式下降。spring boot核心思维约定大于配置,确实革命性地减轻了配置的烦恼。Spring Cloud正是基于这种思维,用约定大于配置的思想整合了大量地分布式开发组件,给开发者带来了很多的方便。

Spring Cloud 为开发者提供了快速构建分布式系统中一些常用模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线)。分布式系统的协调导致了样板模式,使用 Spring Cloud 开发人员可以快速建立实现这些模式的服务和应用程序。它们将适用于任何分布式环境,包括开发人员自己的笔记本电脑、裸机数据中心和托管平台(如 Cloud Foundry)。

Spring Cloud包含了一系列的工具,Netflix Eureka 就是其中最重要的组件之一,它的功能类似于国内的dubbo。提供服务注册发现以及集群部署等一系列微服务最核心功能。服务发现是基于微服务的架构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能很难做到,而且很脆弱。Eureka 是 Netflix 服务发现服务器和客户端。服务器可以配置和部署为高可用性,每个服务器将有关注册服务的状态复制到其他服务器。此外还有hystirx熔断器,用于管理崩溃的微服务,防止千里之堤,溃于蚁穴。zuul网关提供了对外服务的路由管理,还有openfeign者提供了服务调用的功能。有了这些组件的加持,开发起来岂能不如虎添翼。

路漫漫其修远兮,吾将上下而求索。知识是无止境的,创万联日后也会秉承开源技术精神,将自己所思所想,技术经验都分享给各位朋友。也许有人会说,你们这样做究竟为了什么,是灌输思想吗?非也。须知创万联开源社区要想发展壮大就有赖于更多的技术爱好分子的加入,我们此举也是渡人渡己,况且我们的认识很多都是不完整和错误的,如果有人指出错误,我们更是受益匪浅。最近鸿蒙的发布,也采取了开源的策略,可以意识到,技术滴水不漏,自家传的时代已经一去不复返。

欢迎关注创万联公众号,这里提供更多通俗技术分享。

本文参考资料:spring官网:https://spring.io/(大陆访问可能速度较为缓慢。)

我与java曲折的交友过程

随风

对于java的认识,我一开始极其的讨厌。原因很多,更多的原因其实是因为我学习的第一门语言是c++,对于java的语言风格我总是觉得不太适应,而且我那时候认识到了go语言,对于java我总是不屑一顾,觉得它垂垂老矣,没有什么可学的。

这种思维一直延续下去,我很固执,甚至因此和队友争吵起来,坚决否定java的优势。我认为云原生时代,作为一次编译,到处运行的许诺早已经落后于时代。docker的崛起已经使得jvm中间体系所带来的跨平台优势不再重要。关键的是go语言本身的交叉编译能力很强,跨平台这点优势不足以成为我选择java的理由。

然而事实极其打脸,后来的我不得不承认了java,甚至成为了主要开发工具。java固然不简单,但是java的思路是清晰的,我们不得不承认在大型开发中,java的oop机制确实让人头脑清晰而且各种诸如idea的工具也使得开发效率极高,说白是因为我懒,喜欢搬运代码。

但我也意识到java作为编程语言它确实不算优秀,与rust和go等新秀比起来java语言本身确实老气横秋。因为java的抽象机制并不总是有益处的,更多时候造成了代码膨胀和编写困难。因此rust和go语言已经没有类这个概念了。相比于简单而灵活的c语言,java又是十分呆板的代表。注解和各种横行霸道的xml配置,java简单已然不复存在。正所谓人生苦短我学python,在实验室等追求极致速度的地方,许多算法程序java已经没有了身影,高的门槛却低的回报使很多人望而止步。

正如刘汝佳算法入门的书里所说的,java作为一门编程语言好坏参半,甚至混杂着各种坏味道,但是从来没有人敢否认java平台的成功,java是一套技术体系的,其中的jvm可以运行各种字节码编程语言,例如新秀kotlin,java还定义了一整套完备的技术标准,使得web时代加速走进我们,也许我们不敢相信,jsp这种近乎绝迹的东西,当时是如何地风靡一时,就如flash一般。

末尾小编想说,任何事物都有存在的理由,我们不能过于凭自己的喜欢而否定或者赞同某一样东西,小编在实验室工作之余经常感慨现在的人越来越功利了,也许创万联开源组织是我们这些技术人最后的净土吧。

用go语言写一个并发的快速排序

随风

快速排序,相信学过算法的各位大佬一定是再熟悉不过了。快速排序以其出色的性能,以及无需辅助空间,较容易实现而获得了极为广泛的使用。但随着CPU核数的日益增加,如何充分利用多核性能已经成为提高程序性能的又一大重要议题,因而在继续讨论iris框架的时候,我想先讨论一下go语言的杀手锏——并发编程。go语言对并发的原生支持,使其对于多核心利用极为有效。

在讨论并发编程之前,我们先来看看几个概念——进程,线程,协程。进程应该是我们最熟悉的。进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。由于进程需要分配系统资源,如内存之类的,故利用多进程来实现高并发显然是捉襟见肘,极为不实际。就在我们困厄的时候,线程应运而生,通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。当下推出的通用操作系统都引入了线程,以便进一步提高系统的并发性,并把它视为现代操作系统的一个重要指标。许多编程语言对线程的支持都很不错,如java。java有大量的线程操作库,如thread,继承之后重写run方法即可轻松启动一个线程。线程看似轻量,无往而不利,对提高并发量有着极为重要的作用。但它在面对秒杀等场景的时候,线程的缺陷也暴露出来,它始终是一个调度的基本单位,因而能够支持并发的数量也不会太高,普通的个人电脑难以实现百万线程,这时侯协程就应运而生。

协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。可见协程更加轻量,能够实现更高的并发。go语言的groutine正是利用了协程来实现。

那么协程之间如何通讯呢,不能通讯的协程其作用就大大削弱,go语言别出心裁的采用了Chanel实现,其实是一个阻塞队列,当然也可以是带有缓冲的非阻塞的,后面文章会详细讨论。

有了以上的基础知识,不难写出并发快排的代码

import “sync”

func MutiQuickSort(num []int){

lock.Add(1)

QuickSort(num, 0, len(num)-1)

lock.Wait()

}

var lock sync.WaitGroup

func QuickSort(num []int, low, high int) {

defer lock.Done()

if low >= high {

return }

i, j := low, high

key := num[low]

for i < j {

for j > i && num[j] >= key {

j } num[i] = num[j]

for i < j && num[i] < key {

i++ }

num[j] = num[i]

}

num[j] = key lock.Add(2)

go QuickSort(num, low, i-1)

go QuickSort(num, i+1, high)

}

可见用go语言处理并发优雅而方便,不愧为21世纪c语言。

部分来自百度百科,csdn

宇宙最快之go web框架——iris

随风

昨天兴致大发写了一篇go语言的文章,看到不少朋友对go语言还是很感兴趣的。今天兴致大发,决定再写一篇关于go web开发的文章。今天我想介绍的是宇宙最快之go web框架——iris。是不是有点夸张?我本人觉得确实有点夸张,不过iris框架的官方GitHub文档是这么写的,我也就不好反驳了,实际上iris框架的性能确实比spring boot高出很多,而且能满足树莓派等设备需求,轻量简洁,这大概也是go语言的特点吧。

做过后端的各位朋友肯定都知道,重造轮子是一件非常麻烦的事。我们固然可以从socket开始写起,但是这样的开发效率肯定是。。。(不用多说。。)其实java真正厉害的也许不是语言本身,而是附着在java上的众多框架,例如spring。有了这些脚手架,我们就可以站在前人的肩膀上走得更远。

iris的安装很容易,只需要go get -u github.com/kataras/iris,当然前提条件是安装了go编译器,如果不懂安装而对go语言感兴趣的话,也可以私信创万联公众号哦。

先来一段iris框架使用的简单demo

package main

import (
“github.com/kataras/iris”
“github.com/kataras/iris/context”
)

func main() {
app := iris.New()
app.Get(“/”, func(ctx context.Context){

ctx.HTML(“<h1>Welcome</h1>”)

})
app.Run(iris.Addr(“:8080”))
}

将其复制后保存到记事本,然后命名为main.go,打开命令行。go build main.go,打开浏览器输入127.0.0.1:8080/即可以看到welcome显示在浏览器上。是不是感觉很简单,很想尝试一下,那就赶快动手试试吧。

事实上iris为我们包装了路由处理以及完整的mvc框架支持,以及令人兴奋的中间件处理,考试要紧,今天我们就聊到这吧,下期再见。

go语言,未来的新选择

随风

做了一段时间的后端,有苦也有喜悦。在创万联的实战之中使我认识了一种全新的,令人喜悦而又忧虑的新语言——go语言。

go语言的哲学是少即是多。这是go的信条,这与java严密的逻辑体系有所不同。go语言没有泛型,没有类层次,在现代语言中显得有点特立独行。go语言奉行独特的组合思想,你走起来是鸭子你就是鸭子的思想使得go语言具有了独特的灵活。

go语言天生高并发,go语言创建一个协程极度简单。只需要go 函数即可。在多核心时代,这种设计无疑给编程人员带来了很大的方便。利用Chanel 进行消息传递避开了传统多线程互斥锁等操作,尽管不能完全消除,但至少使得高并发编程更加优雅。

go的面向对象编程其实是容易的,它使得类的神秘性不再存在,this指针被暴露眼前,多态虚函数等晦涩概念也无需深究。

当然go的缺点也显而易见,go的生态相对于java是那么的缺乏,以至于构建后端很多时候不得不重造轮子。但相信以后或许这种情况会得到改善,使得我们在写后端时候多一种选择。