• 关于

    处理语言出问题什么情况

    的搜索结果

问题

C语言基础 【精品问答合集】

马铭芳 2019-12-01 20:09:24 24451 浏览量 回答数 13

问题

如何给项目选择最合适的编程语言?

chaipanpan 2019-12-01 21:04:01 9813 浏览量 回答数 0

问题

【Java问答学堂】13期 redis 和 memcached 有什么区别?

剑曼红尘 2020-05-06 14:37:41 0 浏览量 回答数 1

阿里云试用中心,为您提供0门槛上云实践机会!

0元试用32+款产品,最高免费12个月!拨打95187-1,咨询专业上云建议!

回答

【Java问答学堂】13期 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理和特点,就是 redis 实际上是个单线程工作模型,你要是这个都不知道,那后面玩儿 redis 的时候,出了问题岂不是什么都不知道? 还有可能面试官会问问你 redis 和 memcached 的区别,但是 memcached 是早些年各大互联网公司常用的缓存方案,但是现在近几年基本都是 redis,没什么公司用 memcached 了。 面试题剖析 redis 和 memcached 有啥区别? redis 支持复杂的数据结构 redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作。如果需要缓存能够支持更复杂的结构和操作, redis 会是不错的选择。 redis 原生支持集群模式 在 redis3.x 版本中,便能支持 cluster 模式,而 memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据。 性能对比 由于 redis 只使用单核,而 memcached 可以使用多核,所以平均每一个核上 redis 在存储小数据时比 memcached 性能更高。而在 100k 以上的数据中,memcached 性能要高于 redis。虽然 redis 最近也在存储大数据的性能上进行优化,但是比起 memcached,还是稍有逊色。 redis 的线程模型 redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,将产生事件的 socket 压入内存队列中,事件分派器根据 socket 上的事件类型来选择对应的事件处理器进行处理。 文件事件处理器的结构包含 4 个部分: 多个 socketIO 多路复用程序文件事件分派器事件处理器(连接应答处理器、命令请求处理器、命令回复处理器) 多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程序会监听多个 socket,会将产生事件的 socket 放入队列中排队,事件分派器每次从队列中取出一个 socket,根据 socket 的事件类型交给对应的事件处理器进行处理。 来看客户端与 redis 的一次通信过程: 要明白,通信是通过 socket 来完成的,不懂的同学可以先去看一看 socket 网络编程。 首先,redis 服务端进程初始化的时候,会将 server socket 的 AE_READABLE 事件与连接应答处理器关联。 客户端 socket01 向 redis 进程的 server socket 请求建立连接,此时 server socket 会产生一个 AE_READABLE 事件,IO 多路复用程序监听到 server socket 产生的事件后,将该 socket 压入队列中。文件事件分派器从队列中获取 socket,交给连接应答处理器。连接应答处理器会创建一个能与客户端通信的 socket01,并将该 socket01 的 AE_READABLE 事件与命令请求处理器关联。 假设此时客户端发送了一个 set key value 请求,此时 redis 中的 socket01 会产生 AE_READABLE 事件,IO 多路复用程序将 socket01 压入队列,此时事件分派器从队列中获取到 socket01 产生的 AE_READABLE 事件,由于前面 socket01 的 AE_READABLE 事件已经与命令请求处理器关联,因此事件分派器将事件交给命令请求处理器来处理。命令请求处理器读取 socket01 的 key value 并在自己内存中完成 key value 的设置。操作完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。 如果此时客户端准备好接收返回结果了,那么 redis 中的 socket01 会产生一个 AE_WRITABLE 事件,同样压入队列中,事件分派器找到相关联的命令回复处理器,由命令回复处理器对 socket01 输入本次操作的一个结果,比如 ok,之后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联。 这样便完成了一次通信。关于 Redis 的一次通信过程,推荐读者阅读《Redis 设计与实现——黄健宏》进行系统学习。 为啥 redis 单线程模型也能效率这么高? 纯内存操作。核心是基于非阻塞的 IO 多路复用机制。C 语言实现,一般来说,C 语言实现的程序“距离”操作系统更近,执行速度相对会更快。单线程反而避免了多线程的频繁上下文切换问题,预防了多线程可能产生的竞争问题。 往期回顾: 【Java问答学堂】1期 为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景? 【Java问答学堂】2期 如何保证消息队列的高可用? 【Java问答学堂】3期 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性? 【Java问答学堂】4期 如何保证消息的可靠性传输?(如何处理消息丢失的问题?) 【Java问答学堂】5期 如何保证消息的顺序性? 【Java问答学堂】6期 如何解决消息队列的延时以及过期失效问题? 【Java问答学堂】7期 如果让你写一个消息队列,该如何进行架构设计? 【Java问答学堂】8期 es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)? 【Java问答学堂】9期 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊? 【Java问答学堂】10期 es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? 【Java问答学堂】11期 es 生产集群的部署架构是什么?每个索引的数据量大概有多少? 【Java问答学堂】12期 项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?

剑曼红尘 2020-05-06 14:37:53 0 浏览量 回答数 0

问题

Redis 和 Memcached 的区别?Redis 的线程模型是什么?【Java问答学堂】31期

剑曼红尘 2020-06-03 20:28:14 28 浏览量 回答数 1

回答

Kotlin的简介 Kotlin是由JetBrains公司(IDEA开发者)所开发的编程语言,其名称来自于开发团队附近的科特林岛。 多平台开发 JVM :Android; Server-Side Javascript:前端 Native(beta) :开发原生应用 windows、macos、linux Swift与Kotlin非常像 http://nilhcem.com/swift-is-like-kotlin/ kotlin发展历程 image.png java发展历程 image.png JVM语言的原理 image.png JVM规范与java规范是相互独立的 只要生成的编译文件匹配JVM字节码规范,任何语言都可以由JVM编译运行. Kotlin也是一种JVM语言,完全兼容java,可以与java相互调用;Kotlin语言的设计受到Java、C#、JavaScript、Scala、Groovy等语言的启发 kotlin的特性 下面不会罗列kotlin中具体的语法,会介绍我认为比较重要的特性,以及特性背后的东西。 类型推断 空类型设计 函数式编程 类型推断 image.png 类型推断是指编程语言中在编译期自动推导出值的数据类型。推断类型的能力让很多编程任务变得容易,让程序员可以忽略类型标注的同时仍然允许类型检查。 在开发环境中,我们往往写出表达式,然后可以用快捷键来生成变量声明,往往都是很准的,这说明了编译器其实是可以很准确的推断出来类型的。编程语言所具备的类型推断能力可以把类型声明的任务由开发者转到了编译器. java中声明变量的方式是类型写在最前面,后面跟着变量名,这就迫使开发者在声明变量时就要先思考变量的类型要定义成什么,而在一些情况下比如使用集合、泛型类型的变量,定义类型就会变得比较繁琐。 Kotlin中声明变量,类型可以省略,或者放到变量名后面,这可以降低类型的权重,从必选变为可选,降低开发者思维负担。java10中也引入了类型推断。 Javascript中声明变量也是用关键字var,但是还是有本质区别的,Kotlin中的类型推断并不是变成动态类型、弱类型,类型仍然是在编译期就已经决定了的,Kotlin仍然是静态类型、强类型的编程语言。javascript由于是弱类型语言,同一个变量可以不经过强制类型转换就被赋不同数据类型的值, 编程语言的一个趋势就是抽象程度越来越高,编译器做更多的事情。 空类型设计 空类型的由来 image.png 托尼·霍尔(Tony Hoare),图灵奖得主 托尼·霍尔是ALGOL语言的设计者,该语言在编程语言发展历史上非常重要,对其他编程语言产生重大影响,大多数近代编程语言(包括C语言)皆使用类似ALGOL的语法。他在一次大会上讨论了null应用的设计: “我把 null 引用称为自己的十亿美元错误。它的发明是在1965 年,那时我用一个面向对象语言( ALGOL W )设计了第一个全面的引用类型系统。我加入了null引用设计,仅仅是因为实现起来非常容易。它导致了数不清的错误、漏洞和系统崩溃,可能在之后 40 年中造成了十亿美元的损失。” null引用存在的问题 以java为例,看null引用的设计到底存在哪些问题 空指针问题NPE 编译时不能对空指针做出检查,运行时访问null对象就会出现错误,这个就是工程中常见的空指针异常。 null本身没有语义,会存在歧义 值未被初始化 值不存在 也许表示一种状态 逻辑上有漏洞 Java中,null可以赋值给任何引用,比如赋值给String类型变量,String a = null,但是null并不是String类型: a instanceof String 返回的是false,这个其实是有些矛盾的。所以当持有一个String类型的变量,就存在两种情况,null或者真正的String. 解决NPE的方式 防御式代码 在访问对象前判空,但会有冗余代码;会规避问题,而隐藏真正的问题 抛出异常给调用方处理 方法中传参传入的空值、无效值,抛出受检查异常给上层调用方 增加注解 Android中可以增加@NonNull注解,编译时做额外检查 空状态对象设计模式 空状态对象是一个实现接口但是不做任何业务逻辑的对象,可以取代判空检查;这样的空状态对象也可以在数据不可用的时候提供默认的行为 java8 Optional类 java8中引入了Optional类,来解决广泛存在的null引用问题.官方javadoc文档介绍 A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value. Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present). 来看一下是如何实现的。 举一个访问对象读取熟悉的例子 java 8 之前 : image.png java 8: image.png 总结: 1.用Optional还是会比较繁琐,这个也说明了设计一个替代null的方案还是比较难的。 optional的耗时大约是普通判空的数十倍,主要是涉及泛型、使用时多创键了一个对象的创建;数据比较大时,会造成性能损失。 java8 引入Optional的意义在于提示调用者,用特殊类型包装的变量可能为空,在使用取出时需要判断 Kotlin的空类型设计 Kotlin中引入了可空类型和不可空类型的区分,可以区分一个引用可以容纳null,还是不能容纳null。 String vs String? String 类型表示变量不能为空,String?则表示变量可以为空 String?含义是String or null.这两种是不同的类型. 比如: var a:String = “abc” //ok var a:String = null //不允许 var b :String? = null //ok a=b // 不允许 String?类型的值不能给String类型的值赋值 这样就将类型分成了可空类型和不可能类型,每一个类型都有这样的处理;Kotlin中访问非空类型变量永远不会出现空指针异常。 同样上面的例子,采用Kotlin去写,就会简洁很多 image.png 编程范式-函数式编程 编程范式是什么? 编程范式是程序员看待程序和写程序的观点 主要的类型 非结构化编程 结构化编程 面向对象编程 命令式编程 函数式编程 这些类型并不是彼此互斥的,而是按照不同的维度做的划分,一种编程语言可能都支持多个编程范式 非结构化编程 第一代的高级语言往往是非结构化编程 比如 BASIC语言 每一行的代码前面都有一个数字作为行号,通常使用GOTO的跳跃指令来实现判断和循环. 看一下下面这段代码是做什么的: image.png 实际上做的是:程序在屏幕上显示数字 1 到 10 及其对应的平方 采用这种方式写程序,大量的使用goto实现逻辑的跳转,代码一长,可读性和维护性就比较差了,形成“面条式代码” 结构化编程 采用顺序、分支、循环结构来表达,禁用或者少用GOTO; 并用子程序来组织代码,采用自顶向下的方式来写程序 代表语言是C语言 实现同样的逻辑: image.png 可见采用结构化编程,代码的逻辑会更清晰。 面向对象编程 思想: 将计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。 特性: 封装性、继承性、多态性。 命令式编程 把计算机程序视为一系列的命令集合 主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么。 “先做这,再做那”,强调“怎么做” 实现: 用变量来储存数据,用语句来执行指令,改变变量状态。 基本所有的常见的编程语言都具有此范式 函数式编程 声明式语法,描述要什么,而不是怎么做 类似于SQL语句 语言: kotlin swift python javascript scala 函数是第一等公民 可以赋值给变量,可作为参数传入另一个函数,也可作为函数的返回值 纯函数 y=f(x) 只要输入相同,返回值不变 没有副作用:不修改函数的外部状态 举个栗子 公司部门要进行outing,去哪里是个问题,要考虑多个因素,比如花费、距离、天数等等,有多个备选地点进行选择。 定义一个数据类: image.png 要进行筛选了,分别用sql,kotlin,java来实现 找出花费低于2000元的outing地点信息 SQL image.png Kotlin image.png java 7 image.png 可见kotin的写法还是比较接近于sql的思想的,声明式的写法,而不管具体如何实现;其中的:place->place.money<2000 就是函数,可以作为参数传递给fliter这个高阶函数;而且这个函数没有副作用,不改变外部状态。 再来一个复杂一点的: 找出花费低于5000元,时间不多于4天,按照距离排序的outing地点名称 SQL image.png Kotlin: image.png java 7 image.png 由此可见用kotlin的函数式写法,会更简洁,逻辑也更清晰,这段代码的目标一目了然,这种清晰在于实现了业务逻辑与控制逻辑的分离,业务逻辑就是由函数实现的,比如place->place.money<500,而控制逻辑是由filter,sorterBy等高阶函数实现的。 而java的传统写法是基于对数据的操作,避免不了遍历的操作,业务逻辑与控制逻辑交织在了一起,这段代码的目的就不是那么容易清晰看到的了。 总结 kotlin是实用的现代编程语言,吸收了众多编程语言的优点,支持类型推断、空类型安全、函数式编程、DSL等特性,非常值得学习和使用。

问问小秘 2020-04-30 16:33:40 0 浏览量 回答数 0

回答

python程序员的特征 Python语法优雅,功能强大,开发效率高。和其他语言相比,python最大的好处是接近自然语言,基本上不用考虑语法细节。所以,知乎上有网友是这么比喻学Python的:当土著拿到猎枪之后,他们射箭的技能退化严重,但因为食物更多了,厨艺有了长足的进展。当你不再为一些细枝末节的事担心之后,你就可以把注意力集中在另外一些问题上了。 python程序员明显特征就是:“懒” 他们一般都信奉极简主义,讨厌复杂的东西。以往追求高速运行,如今追求一字千金。(就是不喜欢打字)他们喜欢使用苹果产品。遇事想得多做的少,看起来比较冷静,碰到困难,先google,再行动。 被提bug的反应:你怎么还在用360安全浏览器 Java程序员的特征 和极简主义的Python恰恰相反,Java麾下的程序猿们喜欢码字,百行代码信手拈来,性子会走向两个极端,要么脾气变得暴躁,分分钟被各种报错逼疯;要么被磨得比较耐心,时间再长一点以后,思考问题会比较全面,而且会变得比较呆萌可爱,说话也因为考虑的多,变得啰嗦了。还有就是他们对内存价格那是了如指掌啊。 被提bug的反应:肯定是数据问题!你清下缓存试试、重启下电脑试试 C++程序员的特征 写C++的程序猿都比较沉稳持重,C++的难度极大,普通人不易掌握容易翻车,【珍爱生命,远离C++】但在大神手里简直是如虎添翼,可以被嵌入任何现代处理器中,几乎所有操作系统都支持 C++,跨平台性非常好,要什么有什么。也正因为它的难度系数高,能让c++猿们能够在开发人员里脱颖而出。 他们很少说自己精通XXX,喜欢接受挑战,每件事情都想研究个透彻,有的时候还会有些钻牛角尖,有很强的时间观念,闹钟一设设十几个。还有他们是Bug狂躁症深度患者。 **被提bug的反应: “这真的很奇怪!” “以前从来没有出现过这种情况!” “昨天还运行好好的啊!” “这怎么可能?” “一定是硬件出问题了!” ** C语言程序员的特征 如果把使用各大编程语言比作做菜,C++可能是豪华大宴,炖烤煎炸样样都来,C语言嘛就是干脆利落,一把菜刀走天下,有什么菜不是直接切一切,煮一煮不能解决的呢?C语言的特点很大程度上是简单,容易编译,灵活且贴近底层。 C语言程序员有许多共有的特征,他们做事干脆利落,说话简洁有层次,有点霸道总裁的样子,喜欢用“我觉得吧~”开始话题。 被提bug的反应: 你装的什么版本的类库(jdk) 这谁写的代码 Ruby语言程序员特征 Ruby 是一种简单快捷的面向对象(面向对象程序设计)脚本语言。从程序员的角度看,用 Ruby 写程序是一种非常愉悦的体验。这种愉悦体现在方方面面,包括 Ruby 代码简洁直观、更贴近自然语言、富于表达性、社区友好。 如果把编程语言们看作人的话,那么Ruby就是其中的一个小萝莉。在萌妹砸Ruby的影响下,程序猿们很有可能会变成热情,友善的程序媛… 被提bug的反应: 你为什么要那样操作?” 用户不会像你这么操作的。 PHP程序员特征 这个圈子里,永远有一个”PHP是世界上最好的语言“的冷笑话,能让相亲对象直接拉黑,这语言能不好么(逃),类似的段子已经成了php们的生活调味品。 所以: 玩笑过后言归正传,PHP当然是有它的优势和优点的,社区庞大,积极向上不说,既能面向过程又能面向对象,方便至极,最重要的是极其适合新手小白学习编程,无数程序员入门学习和开发使用。 他们的显著特征是:自信满满,心理承受能力好(不好不行啊)开朗…学了之后明显笑容变多了能淡定从容地自黑。 被提bug的反应: “这应该只是巧合吧!” “我没时间测试所有功能!” “这不可能是我代码的问题! 结论 以上观点无科学实验证明,仅为生活观察所得。一个人的性格很容易被周围环境所影响,而编程环境就是一个影响人性格的环境。所以某种语言用久了,都会和编程语言的特点挂钩。 有人总结,越是学习趋于人类思维方式的编程语言的程序员,性格能开朗点,因为他们是以近似人的思维思考问题,相反像c++这种语言,用久了就会生怕忘记点什么。 加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答 阿里云开发者社区

茶什i 2020-01-06 17:57:28 0 浏览量 回答数 0

问题

10+年程序员总结的20+条经验教训

雅蕾 2019-12-01 21:56:26 7714 浏览量 回答数 0

回答

垃圾收集GC(Garbage Collection)是Java语言的核心技术之一, 在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。针对GC我们这篇文章提出以下几个问题,GC中判定为垃圾的标准,标记垃圾的算法以及回收垃圾的算法。 什么样的对象才是垃圾? 这个问题其实很简单,对于Java对象来讲,如果说这个对象没有被其他对象所引用该对象就是无用的,此对象就被称为垃圾,其占用的内存也就要被销毁。那么自然而然的就引出了我们的第二个问题,判断对象为垃圾的算法都有哪些? 标记垃圾的算法 Java中标记垃圾的算法主要有两种, 引用计数法和可达性分析算法。我们首先来介绍引用计数法。 引用计数法 引用计数法就是给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的,可以当做垃圾收集。这种方法实现起来很简单而且优缺点都很明显。 优点 执行效率高,程序执行受影响较小 缺点 无法检测出循环引用的情况,导致内存泄露

苍霞学子 2020-03-26 09:52:48 0 浏览量 回答数 0

回答

"主题前提 多语言站点包含三个不同方面: 界面翻译 内容 网址路由 尽管它们都以不同的方式互连,但是从CMS的角度来看,它们是使用不同的UI元素进行管理的,并且存储方式也不同。您似乎对自己的实现和对前两个的理解充满信心。问题是关于后一个方面的问题:“ URL转换?我们应该这样做吗?应该以什么方式进行?” URL可以由什么组成? 一个非常重要的事情是,不要对IDN感兴趣。取而代之的是支持音译(也:转录和罗马化)。乍一看,IDN似乎是国际URL的可行选择,但实际上,它不能按广告宣传工作,原因有两个: 某些浏览器会将非ASCII字符(例如'ч'或)'ž'转换为'%D1%87'和'%C5%BE' 如果用户具有自定义主题,则主题的字体很可能没有这些字母的符号 实际上,几年前,我在一个基于Yii的项目(可怕的框架,恕我直言)中尝试了IDN方法。在抓取该解决方案之前,我遇到了上述两个问题。另外,我怀疑这可能是攻击媒介。 可用选项...如我所见。 基本上,您有两个选择,可以抽象为: http://site.tld/[:query]:[:query]决定语言和内容选择的地方 http://site.tld/[:language]/[:query]:[:language]URL的一部分定义语言的选择,[:query]仅用于标识内容 查询是Α和Ω.. 假设您选择http://site.tld/[:query]。 在这种情况下,您有一种主要的语言来源:[:query]段的内容;以及另外两个来源: $_COOKIE['lang']该特定浏览器的价值 HTTP Accept-Language (1),(2)标头中的语言列表 首先,您需要将查询与定义的路由模式之一进行匹配(如果您选择的是Laravel,请在此处阅读)。成功匹配模式后,您需要查找语言。 您将必须遍历模式的所有部分。找到所有这些片段的潜在翻译,并确定使用哪种语言。当(不是“如果”)发生冲突时,将使用两个其他来源(cookie和标头)来解决路由冲突。 例如:http://site.tld/blog/novinka。 那是音译""блог, новинка"",在英语中大约是""blog"", ""latest""。 您已经注意到,俄语中的“блог”将译为“博客”。这意味着对于您的第一部分[:query](在最佳情况下),最终会['en', 'ru']列出可能的语言。然后您进入下一个片段-“ novinka”。可能的列表中可能只有一种语言:['ru']。 当列表中有一项时,您已经成功找到该语言。 但是,如果最终得到2种(例如:俄语和乌克兰语)或更多种可能性..或0种可能性(视情况而定)。您将必须使用Cookie和/或标题才能找到正确的选项。 如果其他所有方法均失败,则选择站点的默认语言。 语言作为参数 替代方法是使用URL,可以将其定义为http://site.tld/[:language]/[:query]。在这种情况下,翻译查询时,您无需猜测语言,因为此时您已经知道要使用哪种语言。 还有另一种语言来源:cookie值。但是,这里没有必要弄乱Accept-Language标头,因为在“冷启动”的情况下(当用户第一次使用自定义查询打开网站时),您不会处理未知数量的可能的语言。 相反,您有3个简单的优先选项: 如果[:language]设置了细分,请使用它 如果$_COOKIE['lang']设置,使用它 使用默认语言 使用该语言时,您只需尝试翻译查询,如果翻译失败,请对该特定段使用“默认值”(基于路由结果)。 这不是第三种选择吗? 是的,从技术上讲,您可以将两种方法结合使用,但这会使过程复杂化,并且只适合那些想要手动更改URL http://site.tld/en/news到http://site.tld/de/news并希望新闻页面更改为德语的人员。 但是即使是这种情况,也可以使用cookie值(其中包含有关先前选择语言的信息)缓解,以减少魔术和希望。 使用哪种方法? 您可能已经猜到了,我建议您将其http://site.tld/[:language]/[:query]作为更明智的选择。 同样在真实的单词情况下,URL中将包含第三大部分:“标题”。如在线商店中的产品名称或新闻站点中的文章标题。 例: http://site.tld/en/news/article/121415/EU-as-global-reserve-currency 在这种情况下'/news/article/121415'将是查询,而'EU-as-global-reserve-currency'标题是。纯粹用于SEO。 可以在Laravel中完成吗? Kinda,但默认情况下不是。 我不太熟悉它,但是据我所知,Laravel使用简单的基于模式的路由机制。要实现多语言URL,您可能必须扩展核心类,因为多语言路由需要访问不同形式的存储(数据库,缓存和/或配置文件)。 已路由。现在怎么办? 结果,您最终将获得两条有价值的信息:当前语言和查询的翻译段。然后,这些值可用于调度将产生结果的类。 基本上,以下网址:(http://site.tld/ru/blog/novinka或不含的版本'/ru')变成了类似 $parameters = [ 'language' => 'ru', 'classname' => 'blog', 'method' => 'latest', ]; 您仅用于调度的对象: $instance = new {$parameter['classname']}; $instance->{'get'.$parameters['method']}( $parameters ); ..或它的某些变体,具体取决于特定的实现。"来源:stack overflow

保持可爱mmm 2020-05-18 10:09:50 0 浏览量 回答数 0

问题

最佳实践多语言网站?mysql

保持可爱mmm 2020-05-18 09:52:23 2 浏览量 回答数 1

回答

算法的本质是解决问题的方法,是思想 在早期的时候,人们遇到新问题,必须要去解决它,经过“冥思苦想”,“反复探索尝试”,    最后总结归纳。这才形成了今天我们学习的各种算法。如果无法领会到解决问题的思想,无法总结归纳,就会有:“学算法有什么用。”。不知道为什么学,自然会认为学了没意义,没有用处。 2.一个算法应该具有以下五个重要的特征: ①有穷性: 算法的有穷性是指算法必须能在执行有限个步骤之后终止,换句话说就是一个算法必须总是在执行有穷步之后结束,且每一步都可在有穷时间内完成。②确定性:算法中的每条指令必须有确切的定义,不会产生二义性,并且对于相同的输入只能得出相同的输出。③可行性:算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步,即每个计算步都可以在有限时间内完成(也称之为有效性)。④输入: 一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件,这些输入取自于某个特定的对象集合。 ⑤输出:一个算法有一个或多个的输出,这些输出是同输入有着特定关系的量,没有输出的算法是毫无意义的。 算法总是要解决特定的问题,问题来源就是算法的输入,期望的结果就是算法的输出,没有输入输出的算法是无意义的。3.算法设计的5个要求:①正确性:最基本要求,算法必须能解决某个问题的需求。②可读性:算法的可读性有助于人的阅读与交流,容易调试和修改。③健壮性:当输入的数据非法时,算法能适当做出反应或进行处理,而不会产生莫名其妙的输出结果。④效率性:算法是为了解决大规模问题,因此需要运行效率足够快。⑤存储性:算法在执行过程中,所需要的最大存储空间,应该尽可能的占用小。效率性与存储性都与问题规模有关,求100人的平均分与求1000人的平均分,同一个算法的所花费的执行时间与存储空间显然是不一样的。 正确性,可读性,健壮性不仅仅是算法设计的要求,而是贯穿整个软件设计层次。单对于算法本身来说,我们最关注的层面是效率性。千万不能死板的认为,算法就是计算机程序。算法是一切解决问题的思想,语言描述,伪代码,流程图,各种符号或者控制表格同样是算法。

行者武松 2019-12-02 01:17:57 0 浏览量 回答数 0

问题

2018python技术问答集锦,希望能给喜欢python的同学一些帮助

技术小能手 2019-12-01 19:31:10 2040 浏览量 回答数 2

问题

[精品问答]Java一百问第一期

问问小秘 2019-12-01 21:51:20 791 浏览量 回答数 1

问题

从HTML中攫取你所需的信息:报错

kun坤 2020-06-08 11:01:51 3 浏览量 回答数 1

问题

10个迷惑新手的Cocoa,Objective-c开发难点和问题? 400 报错

爱吃鱼的程序员 2020-05-31 00:44:29 0 浏览量 回答数 1

问题

关于CDN鉴权配置功能字符转义的那些事!

熊熊君 2019-12-01 21:42:41 3927 浏览量 回答数 3

回答

这是oracle的bug,请下载oracle 最新的jar,连接地址: http://download.oracle.com/otn/utilities_drivers/jdbc/11204/ojdbc6.jar 首先,恭喜楼主问题得解,可喜可贺! 其次,感谢楼主解决问题后的分享。 但是我有几点建议想对楼主谏言(不喜勿看,打扰见谅): 第一,从此问题的最终解决来看。楼主的描述实在是不足以让别人更好的帮助你解决问题。首先,你的标题和你的问题就对不上。其次,关于问题描述,最开始你只是把error的stacktrace信息发布出来,这样别人根本就无法很好的帮你判断问题,后来你对描述还更新过一次,加上了表结构和代码,但实际问题是在于oracle的驱动问题,你的描述也没有突出你用的是oracle的这个重点。为了让别人更好的帮助你,望今后把重点信息表述出来,感谢! 第二,对于问题的解决你也没有描述清楚。首先,prepareStatement这个API的文档说明并不能说明oracle驱动的这个bug,对于问题的解决没有实际的帮助。其次,你附带的那个csdn的帖子里面也对这个bug没有任何明确的说明,而且那个帖子最后的一个回复者所述,换驱动并没有解决同样的问题,这样让读者对此bug的描述和解决难免产生质疑,缺乏可信度。虽然我又去stackoverflow确认过了,确实是oracle的jdbc驱动的问题,但是单就此问题的分享的角度,楼主的答案并没有充分体现出分享的价值。为了给大家带来更好的帮助,望楼主以后在回答的时候能给出更权威可信的答案。 ps:我附上stackoverflow对oracle驱动bug的帖子,作为对楼主的补充,供大家参考:http://stackoverflow.com/questions/277744/jdbc-oracle-arrayindexoutofboundsexception 文中还描述了一种workaround的解决方案,请大家参阅。 以上!万谢!大家看过来,这个才是最佳答案^_^谢谢提醒,以后多加注意!这。。。。。这个和8个有什么关系啊,直觉上感觉是你传进去的paras的size根本就不够吧。你调试看一下当时的数据是怎么样的?而且你这标题。。。是怎么回事?你这错误是在save时候的,为什么标题是说getModel的问题?你是说getModel没有给你取到9个属性么?回复 @小兵一枚:呵呵,什么要侮辱,有问题提提怎么了,不要盲目的崇拜!问题原因是oracle的bug!回复 @蚂蚁蚂蚁:不要侮辱强大的JFinal亲莫非你们都是小表! java.lang.ArrayIndexOutOfBoundsException: 8 下次提问还是先检查下错误再提吧 查了查api,如下: prepareStatementPreparedStatementprepareStatement(Stringsql,String[]columnNames)throwsSQLException创建一个能返回由给定数组指定的自动生成键的默认PreparedStatement对象。此数组包含目标表中列的名称,而目标表包含应该返回的自动生成键。如果SQL语句不是INSERT语句,或者SQL语言能够返回自动生成的键(这类语句的列表是特定于供应商的),则驱动程序将忽略该数组。带IN参数或不带IN参数的SQL语句都可以被预编辑并存储在PreparedStatement对象中。然后可以使用此对象多次有效地执行该语句。注:为了处理受益于预编译的带参数SQL语句,此方法进行了优化。如果驱动程序支持预编译,则prepareStatement方法将该语句发送给数据库进行预编译。一些驱动程序可能不支持预编译。在这种情况下,执行PreparedStatement对象之前无法将语句发送给数据库。这对用户没有直接影响;但它的确会影响哪些方法将抛出某些SQLException。使用返回的PreparedStatement对象创建的结果集在默认情况下类型为TYPE_FORWARD_ONLY,并带有CONCUR_READ_ONLY并发级别。已创建结果集的可保存性可调用getHoldability()确定。参数:sql-可能包含一个或多个'?'IN参数占位符的SQL语句columnNames-列名称数组,这些名称指示应该从一个或多个插入行中返回的那些列返回:一个包含预编译语句的新PreparedStatement对象,该对象能够返回由给定列名称数组指定的自动生成键抛出:SQLException-如果发生数据库访问错误,或者在关闭的连接上调用此方法SQLFeatureNotSupportedException-如果JDBC驱动程序不支持此方法 嗯嗯,这才是正解吗感谢楼主解决问题后回来分享,此贴应该放在技术分享区哈 

爱吃鱼的程序员 2020-06-23 11:59:19 0 浏览量 回答数 0

问题

C++面向对象【问答合集】

马铭芳 2019-12-01 20:19:13 1780 浏览量 回答数 1

回答

如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本, 你会选择哪本书呢。我希望这个书单列表内容丰富,可以涵盖很多东西。” 1、《代码大全》 史蒂夫·迈克康奈尔 推荐数:1684 “优秀的编程实践的百科全书,《代码大全》注重个人技术,其中所有东西加起来, 就是我们本能所说的“编写整洁的代码”。这本书有50页在谈论代码布局。” —— Joel Spolsky 对于新手来说,这本书中的观念有点高阶了。到你准备阅读此书时,你应该已经知道并实践过书中99%的观念。– esac Steve McConnell的原作《代码大全》(第1版)是公认的关于编程的最佳实践指南之一, 在过去的十多年间,本书一直在帮助开发人员编写更好的软件。 现在,作者将这本经典著作全新演绎,融入了最前沿的实践技术,加入了上百个崭新的代码示例, 充分展示了软件构建的艺术性和科学性。 McConnell汇集了来自研究机构、学术界以及业界日常实践的主要知识, 把最高效的技术和最重要的原理交织融会为这本既清晰又实用的指南。 无论您的经验水平如何,也不管您在怎样的开发环境中工作,也无论项目是大是小, 本书都将激发您的思维并帮助您构建高品质的代码。 《代码大全(第2版))》做了全面的更新,增加了很多与时俱进的内容,包括对新语言、新的开发过程与方法论的讨论等等。 2、《程序员修炼之道》 推荐数:1504 对于那些已经学习过编程机制的程序员来说,这是一本卓越的书。 或许他们还是在校生,但对要自己做什么,还感觉不是很安全。 就像草图和架构之间的差别。虽然你在学校课堂上学到的是画图,你也可以画的很漂亮, 但如果你觉得你不太知道从哪儿下手,如果某人要你独自画一个P2P的音乐交换网络图,那这本书就适合你了。—— Joel 《程序员修炼之道:从小工到专家》内容简介:《程序员修炼之道》由一系列独立的部分组成, 涵盖的主题从个人责任、职业发展,知道用于使代码保持灵活、并且易于改编和复用的各种架构技术, 利用许多富有娱乐性的奇闻轶事、有思想性的例子及有趣的类比, 全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。 无论你是初学者,是有经验的程序员,还是软件项目经理,《程序员修炼之道:从小工到专家》都适合你阅读。 3、《计算机程序的构造和解释》 推荐数:916 就个人而言,这本书目前为止对我影响醉倒的一本编程书。 《代码大全》、《重构》和《设计模式》这些经典书会教给你高效的工作习惯和交易细节。 其他像《人件集》、《计算机编程心理学》和《人月神话》这些书会深入软件开发的心理层面。 其他书籍则处理算法。这些书都有自己所属的位置。 然而《计算机程序的构造和解释》与这些不同。 这是一本会启发你的书,它会燃起你编写出色程序的热情; 它还将教会你认识并欣赏美; 它会让你有种敬畏,让你难以抑制地渴望学习更多的东西。 其他书或许会让你成为一位更出色的程序员,但此书将一定会让你成为一名程序员。 同时,你将会学到其他东西,函数式编程(第三章)、惰性计算、元编程、虚拟机、解释器和编译器。 一些人认为此书不适合新手。 个人认为,虽然我并不完全认同要有一些编程经验才能读此书,但我还是一定推荐给初学者。 毕竟这本书是写给著名的6.001,是麻省理工学院的入门编程课程。 此书或许需要多做努力(尤其你在做练习的时候,你也应当如此),但这个价是对得起这本书的。 4、《C程序设计语言》 推荐数:774 这本书简洁易读,会教给你三件事:C 编程语言;如何像程序员一样思考;底层计算模型。 (这对理解“底层”非常重要)—— Nathan 《C程序设计语言》(第2版新版)讲述深入浅出,配合典型例证,通俗易懂,实用性强, 适合作为大专院校计算机专业或非计算机专业的C语言教材,也可以作为从事计算机相关软硬件开发的技术人员的参考书。 《C程序设计语言》(第2版新版)原著即为C语言的设计者之一Dennis M.Ritchie和著名的计算机科学家Brian W.Kernighan合著的 一本介绍C语言的权威经典著作。 我们现在见到的大量论述C语言程序设计的教材和专著均以此书为蓝本。 原著第1版中介绍的C语言成为后来广泛使用的C语言版本——标准C的基础。 人们熟知的“hello,world”程序就是由本书首次引入的,现在,这一程序已经成为所有程序设计语言入门的第一课。 5、《算法导论》 推荐数:671 《代码大全》教你如何正确编程; 《人月神话》教你如何正确管理; 《设计模式》教你如何正确设计…… 在我看来,代码只是一个工具,并非精髓。 开发软件的主要部分是创建新算法或重新实现现有算法。 其他部分则像重新组装乐高砖块或创建“管理”层。 我依然梦想这样的工作,我的大部分时间(>50%)是在写算法,其他“管理”细节则留给其他人…… —— Ran Biron 经典的算法书,被亚马逊网,《程序员》等评选为2006年最受读者喜爱的十大IT图书之一。 算法领域的标准教材,全球多所知名大学选用 MIT名师联手铸就,被誉为“计算机算法的圣经” 编写上采用了“五个一”,即一章介绍一个算法、一种设计技术、一个应用领域和一个相关话题。 6、《重构:改善既有代码的设计》 推荐数:617 《重构:改善既有代码的设计》清晰地揭示了重构的过程,解释了重构的原理和最佳实践方式, 并给出了何时以及何地应该开始挖掘代码以求改善。 书中给出了70多个可行的重构,每个重构都介绍了一种经过验证的代码变换手法的动机和技术。 《重构:改善既有代码的设计》提出的重构准则将帮助你一次一小步地修改你的代码,从而减少了开发过程中的风险。 《重构:改善既有代码的设计》适合软件开发人员、项目管理人员等阅读, 也可作为高等院校计算机及相关专业师生的参考读物。 我想我不得不推荐《重构》:改进现有代码的设计。—— Martin 我必须承认,我最喜欢的编程语录是出自这本书:任何一个傻瓜都能写出计算机能理解的程序, 而优秀的程序员却能写出别人能读得懂的程序。—— Martin Fowler 7、《设计模式》 推荐数:617 自1995年出版以来,本书一直名列Amazon和各大书店销售榜前列。 近10年后,本书仍是Addison-Wesley公司2003年最畅销的图书之一。 中文版销售逾4万册。 就我而言,我认为四人帮编著的《设计模式》是一本极为有用的书。 虽然此书并不像其他建议一样有关“元”编程,但它强调封装诸如模式一类的优秀编程技术, 因而鼓励其他人提出新模式和反模式(antipatterns),并运用于编程对话中。—— Chris Jester-Young 8、《人月神话》 推荐数:588 在软件领域,很少能有像《人月神话》一样具有深远影响力并且畅销不衰的著作。 Brooks博士为人们管理复杂项目提供了最具洞察力的见解。 既有很多发人深省的观点,又有大量软件工程的实践。 本书内容来自Brooks博士在IBM公司System/360家族和OS/360中的项目管理经验。 该书英文原版一经面世,即引起业内人士的强烈反响,后又译为德、法、日、俄中等多种语言,全球销量数百万册。 确立了其在行业内的经典地位。 9、《计算机程序设计艺术》 推荐数:542 《计算机程序设计艺术》系列著作对计算机领域产生了深远的影响。 这一系列堪称一项浩大的工程,自1962年开始编写,计划出版7卷,目前已经出版了4卷。 《美国科学家》杂志曾将这套书与爱因斯坦的《相对论》等书并列称为20世纪最重要的12本物理学著作。 目前Knuth正将毕生精力投入到这部史诗性著作的撰写中。 这是高德纳倾注心血写的一本书。—— Peter Coulton 10、《编译原理》(龙书) 推荐数:462 我很奇怪,居然没人提到龙书。(或许已有推荐,我没有看到)。 我从没忘过此书的第一版封面。 此书让我知道了编译器是多么地神奇绝妙。- DB 11、《深入浅出设计模式》 推荐数:445 强大的写作阵容。 《Head First设计模式》(中文版) 作者Eric Freeman; ElElisabeth Freeman是作家、讲师和技术顾问。 Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。 Kathy Sierra(javaranch.com的创始人)FHBert Bates是畅销的HeadFirst系列书籍的创立者,也是Sun公司Java开发员认证考试的开发者。 本书的产品设计应用神经生物学、认知科学,以及学习理论,这使得这本书能够将这些知识深深地印在你的脑海里, 不容易被遗忘。 本书的编写方式采用引导式教学,不直接告诉你该怎么做,而是利用故事当作引子,带领读者思考并想办法解决问题。 解决问题的过程中又会产生一些新的问题,再继续思考、继续解决问题,这样可以加深体会。 作者以大量的生活化故事当背景,例如第1章是鸭子,第2章是气象站,第3章是咖啡店, 书中搭配大量的插图(几乎每一页都有图),所以阅读起来生动有趣,不会感觉到昏昏欲睡。 作者还利用歪歪斜斜的手写字体,增加“现场感”。 精心设计许多爆笑的对白,让学习过程不会太枯燥。 还有模式告白节目,将设计模式拟人化成节目来宾,畅谈其内在的一切。 每一章都有数目不等的测验题。 每章最后有一页要点整理,这也是精华所在,我都是利用这一页做复习。 我知道四人帮的《设计模式》是一本标准书,但倒不如先看看这部大部头,此书更为简易。 一旦你了解了解了基本原则,可以去看四人帮的那本圣经了。- Calanus 12、《哥德尔、艾舍尔、巴赫书:集异璧之大成》 推荐数:437 如果下昂真正深入阅读,我推荐道格拉斯·侯世达(Douglas Hofstadter)的《哥德尔、艾舍尔、巴赫书》。 他极为深入研究了程序员每日都要面对的问题:递归、验证、证明和布尔代数。 这是一本很出色的读物,难度不大,偶尔有挑战,一旦你要鏖战到底,将是非常值得的。 – Jonik 13、《代码整洁之道》 推荐数:329 细节之中自有天地,整洁成就卓越代码 尽管糟糕的代码也能运行,但如果代码不整洁,会使整个开发团队泥足深陷, 写得不好的代码每年都要耗费难以计数的时间和资源。 然而这种情况并非无法避免。 著名软件专家RoberfC.Marlin在《代码整洁之道》中为你呈现出了革命性的视野。 Martin携同ObjectMetltor公司的同事,从他们有关整洁代码的最佳敏捷实践中提炼出软件技艺的价值观, 以飨读者,让你成为更优秀的程序员——只要你着手研读《代码整洁之道》。 阅读《代码整洁之道》需要你做些什么呢。你将阅读代码——大量代码。 《代码整洁之道》促使你思考代码中何谓正确,何谓错误。 更重要的是,《代码整洁之道》将促使你重新评估自己的专业价值观,以及对自己技艺的承诺。 从《代码整洁之道》中可以学到: 好代码和糟糕的代码之间的区别; 如何编写好代码,如何将糟糕的代码转化为好代码; 如何创建好名称、好函数、好对象和好类; 如何格式化代码以实现其可读性的最大化; 如何在不妨碍代码逻辑的前提下充分实现错误处理; 如何进行单元测试和测试驱动开发。 虽然《代码整洁之道》和《代码大全》有很多共同之处,但它有更为简洁更为实际的清晰例子。 – Craig P. Motlin 14、《Effective C++》和《More Effective C++》 推荐数:297 在我职业生涯早期,Scott Meyer的《Effective C++》和后续的《More Effective C++》都对我的编程能力有着直接影响。 正如当时的一位朋友所说,这些书缩短你培养编程技能的过程,而其他人可能要花费数年。 去年对我影响最大的一本书是《大教堂与市集》,该书教会我很有关开源开发过程如何运作,和如何处理我代码中的Bug。 – John Channing 15、《编程珠玑》 推荐数:282 多年以来,当程序员们推选出最心爱的计算机图书时,《编程珠玑》总是位列前列。 正如自然界里珍珠出自细沙对牡蛎的磨砺,计算机科学大师Jon Bentley以其独有的洞察力和创造力, 从磨砺程序员的实际问题中凝结出一篇篇不朽的编程“珠玑”, 成为世界计算机界名刊《ACM通讯》历史上最受欢迎的专栏, 最终结集为两部不朽的计算机科学经典名著,影响和激励着一代又一代程序员和计算机科学工作者。 本书为第一卷,主要讨论计算机科学中最本质的问题:如何正确选择和高效地实现算法。 尽管我不得不羞愧地承认,书中一半的东西我都没有理解,但我真的推荐《编程珠玑》,书中有些令人惊奇的东西。 – Matt Warren 16、《修改代码的艺术》by Michael Feathers 本书是继《重构》和《重构与模式》之后探讨修改代码技术的又一里程碑式的著作, 而且从涵盖面和深度上都超过了前两部经典。 书中不仅讲述面向对象语言(Java、C#和C++)代码,也有专章讨论C这样的过程式语言。 作者将理解、测试和修改代码的原理、技术和最新工具(自动化重构工具、单元测试框架、仿对象、集成测试框架等), 与解依赖技术和大量开发和设计优秀代码的原则、最佳实践相结合,许多内容非常深入,而且常常发前人所未发。 书中处处体现出作者独到的洞察力,以及多年开发和指导软件项目所积累的丰富经验和深厚功力。 通过这部集大成之作,你不仅能掌握最顶尖的修改代码技术,还可以大大提高对代码和软件开发的领悟力。 我认为没有任何一本书能向这本书一样影响了我的编程观点。 它明确地告诉你如何处理其他人的代码,含蓄地教会你避免哪些(以及为什么要避免)。- Wolfbyte 同意。很多开发人员讨论用干净的石板来编写软件。 但我想几乎所有开发人员的某些时候是在吃其他开发人员的狗食。– Bernard Dy 17、《编码:隐匿在计算机软硬件背后的语言》 这是一本讲述计算机工作原理的书。 不过,你千万不要因为“工作原理”之类的字眼就武断地认为,它是晦涩而难懂的。 作者用丰富的想象和清晰的笔墨将看似繁杂的理论阐述得通俗易懂,你丝毫不会感到枯燥和生硬。 更重要的是,你会因此而获得对计算机工作原理较深刻的理解。 这种理解不是抽象层面上的,而是具有一定深度的,这种深度甚至不逊于“电气工程师”和“程序员”的理解。 不管你是计算机高手,还是对这个神奇的机器充满敬畏之心的菜鸟, 都不妨翻阅一下《编码:隐匿在计算机软硬件背后的语言》,读一读大师的经典作品,必然会有收获。 我推荐Charles Petzold的《编码》。 在这个充满工具和IDE的年代,很多复杂度已经从程序员那“抽取”走了,这本书一本开眼之作。 – hemil 18、《禅与摩托车维修艺术 / Zen and the Art of Motorcycle Maintenance》 对我影响最大的那本书是 Robert Pirsig 的《禅与摩托车维修艺术》。 不管你做什么事,总是要力求完美,彻底了解你手中的工具和任务,更为重要的是, 要有乐趣(因为如果你做事有乐趣,一切将自发引向更好的结果)。 – akr 19、《Peopleware / 人件集:人性化的软件开发》 Demarco 和 Lister 表明,软件开发中的首要问题是人,并非技术。 他们的答案并不简单,只是令人难以置信的成功。 第二版新增加了八章内容。 – Eduardo Molteni 20、《Coders at Work / 编程人生》 这是一本访谈笔录,记录了当今最具个人魅力的15位软件先驱的编程生涯。 包括DonaldKnuth、Jamie Zawinski、Joshua Bloch、Ken Thompson等在内的业界传奇人物,为我们讲述了 他们是怎么学习编程的,在编程过程中发现了什么以及他们对未来的看法, 并对诸如应该如何设计软件等长久以来一直困扰很多程序员的问题谈了自己的观点。 一本非常有影响力的书,可以从中学到一些业界顶级人士的经验,了解他们如何思考并工作。 – Jahanzeb Farooq 21、《Surely You’re Joking, Mr. Feynman! / 别闹了,费曼先生。》 虽然这本书可能有点偏题,但不管你信不信,这本书曾在计算机科学专业课程的阅读列表之上。 一个优秀的角色模型,一本有关好奇心的优秀书籍。 – mike511 22、《Effective Java 中文版》 此书第二版教你如何编写漂亮并高效的代码,虽然这是一本Java书,但其中有很多跨语言的理念。 – Marcio Aguiar 23、《Patterns of Enterprise Application Architecture / 企业应用架构模式》 很奇怪,还没人推荐 Martin Fowler 的《企业应用架构模式》- levi rosol 24、《The Little Schemer》和《The Seasoned Schemer》 nmiranda 这两本是LISP的英文书,尚无中文版。 美国东北大学网站上也有电子版。 25、《交互设计之路》英文名:《The Inmates Are Running The Asylum: Why High Tech Products Drive Us Crazy and How to Restore the Sanity》该书作者:Alan Cooper,人称Visual Basic之父,交互设计之父。 本书是基于众多商务案例,讲述如何创建更好的、高客户忠诚度的软件产品和基于软件的高科技产品的书。 本书列举了很多真实可信的实际例子,说明目前在软件产品和基于软件的高科技产品中,普遍存在着“难用”的问题。 作者认为,“难用”问题是由这些产品中存在着的高度“认知摩擦”引起的, 而产生这个问题的根源在于现今软件开发过程中欠缺了一个为用户利益着想的前期“交互设计”阶段。 “难用”的产品不仅损害了用户的利益,最终也将导致企业的失败。 本书通过一些生动的实例,让人信服地讲述了由作者倡导的“目标导向”交互设计方法在解决“难用”问题方面的有效性, 证实了只有改变现有观念,才能有效地在开发过程中引入交互设计,将产品的设计引向成功。 本书虽然是一本面向商务人员而编写的书,但也适合于所有参与软件产品和基于软件的高科技产品开发的专业人士, 以及关心软件行业和高科技行业现状与发展的人士阅读。 他还有另一本中文版著作:《About Face 3 交互设计精髓》 26、《Why’s (Poignant) Guide to Ruby 》 如果你不是程序员,阅读此书可能会很有趣,但如果你已经是个程序员,可能会有点乏味。 27、《Unix编程艺术》 It is useful regardless operating system you use. – J.F. Sebastian 不管你使用什么操作系统,这本书都很有用。 – J.F. Sebastian 28、《高效程序员的45个习惯:敏捷开发修炼之道》 45个习惯,分为7个方面:工作态度、学习、软件交付、反馈、编码、调试和协作。 每一个具体的习惯里,一开始提出一个谬论,然后展开分析,之后有正队性地提出正确的做法,并设身处地地讲出了正确做法给你个人的“切身感受”,最后列出几条注意事项,帮助你修正自己的做法(“平衡的艺术”)。 29、《测试驱动开发》 前面已经提到的很多书都启发了我,并影响了我,但这本书每位程序员都应该读。 它向我展示了单元测试和TDD的重要性,并让我很快上手。 – Curro 我不关心你的代码有多好或优雅。 如果你没有测试,你或许就如同没有编写代码。 这本书得到的推荐数应该更高些。 人们讨论编写用户喜欢的软件,或既设计出色并健壮的高效代码,但如果你的软件有一堆bug,谈论那些东西毫无意义。– Adam Gent 30、《点石成金:访客至上的网页设计秘笈》 可用性设计是Web设计中最重要也是难度最大的一项任务。 《点石成金-访客至上的网页设计秘笈(原书第二版)》作者根据多年从业的经验,剖析用户的心理, 在用户使用的模式、为扫描进行设计、导航设计、主页布局、可用性测试等方面提出了许多独特的观点, 并给出了大量简单、易行的可用性设计的建议。 本书短小精炼,语言轻松诙谐,书中穿插大量色彩丰富的屏幕截图、趣味丛生的卡通插图以及包含大量信息的图表, 使枯燥的设计原理变得平易近人。 本书适合从事Web设计和Web开发的技术人员阅读,特别适合为如何留住访问者而苦恼的网站/网页设计人员阅读。 这是一本关于Web设计原则而不是Web设计技术的书。 本书作者是Web设计专家,具有丰富的实践经验。 他用幽默的语言为你揭示Web设计中重要但却容易被忽视的问题,只需几个小时, 你便能对照书中讲授的设计原则找到网站设计的症结所在,令你的网站焕然一新。

青衫无名 2019-12-02 01:20:04 0 浏览量 回答数 0

问题

【精品问答】Java技术1000问(1)

问问小秘 2019-12-01 21:57:43 37578 浏览量 回答数 11

回答

原版英文链接:点击这里 作者 | Md Kamaruzzaman 译者 | 无明 策划 | 小智 基础设施:条条道路通云端 对于云厂商来说,2019 年是硕果累累的一年。不仅初创公司在使用云计算,那些很注重安全的“保守派”公司(如政府机构、医疗保健机构、银行、保险公司,甚至是美国五角大楼)也在迁移到云端。这种趋势在 2020 年将会继续,大大小小的公司都将(或者至少有计划)迁移到云端。Gartner 公司最近发布了一个数字: 如果你是一个还在考虑要不要迁移到云端的决策者,不妨重新审视一下你的策略。如果你是一个独立开发者,并且还没使用过云基础设施,那么完全可以在 2020 年尝试一下。很多大型的云厂商(如亚马逊、微软、谷歌)都提供了免费的体验机会。谷歌在这方面做得特别大方,它提供了价值 300 美元的一年免费服务。 策划注:阿里、腾讯、华为等国内云厂商同样有免费云服务试用产品。 云平台:亚马逊领头,其他跟上 作为第一大云厂商,亚马逊在 2019 年可谓风生水起。凭借其丰富的产品组合,亚马逊将把它的优势延续到 2020 年。Canalys 发布的 2019 年第三季度报告指出,大型云厂商(AWS、Azure、GCP)占据 56% 的市场份额,其中 AWS 独享 32.6%。 其他云厂商也在努力缩短与 AWS 之间的差距。微软把主要目标转向了大型企业。最近,微软打败了亚马逊,从美国五角大楼拿到了一个 100 亿美元的大单子。这个单子将提升 Azure 的声誉,同时削弱 AWS 的士气。 谷歌一直在推动 CNCF,实现云计算运维的标准化。谷歌的长期目标是让云迁移变得更容易,方便企业从 AWS 迁移到 GCP。IBM 之前斥资 360 亿美元收购了 RedHat,也想要在云计算市场占有一席之地。 在亚太地区,阿里云市场规模超过了 AWS、Azure 的总和,全球排名第三。中国国内腾讯云等企业的增长势头也十分迅猛。 2020 年将出现更多的并购。当然,很多初创公司将会带来新的想法和创新,例如多云服务。因为竞争激烈,这些公司只能从降价和推出更多的创新产品来获取利润。 容器化:Kubernetes 将会更酷 在容器编排领域,虽然一度出现了“三足鼎立”(Kubernetes、Docker Swarm 和 Mesos),但 Kubernetes 最终脱颖而出,成为绝对的赢家。云是一个分布式系统,而 Kubernetes 是它的 OS(分布式的 Linux)。2019 年北美 KubeCon+CloudNativeCon 大会的参会者达到了 12000 名,比 2018 年增长了 50%。以下是过去 4 年参会人数的增长情况。 在 2020 年,Kubernetes 不仅不会后退,只会变得越来越强,你完全可以把赌注压在 Kubernetes 身上。另外值得一提的是,Migrantis 最近收购了 Docker Enterprise,不过收购数额不详。 几年前,人们张口闭口说的都是 Docker,而现在换成了 Kubernetes。Docker 在它的全盛时期未能盈利,反而在优势渐退几年之后才尝试变现。这再次说明,在现代技术世界,时机就是一切。 软件架构:微服务将成为主流 谷歌趋势表明,微服务架构范式在 2019 年持续增长了一整年。 随着软件行业整体逐步迁移到云端,微服务也将成为占主导地位的架构范式。微服务架构崛起的一个主要原因是它与云原生完美契合,可以实现快速的软件开发。我在之前的一篇博文中解释了微服务架构的基本原则及其优势和劣势。 https://towardsdatascience.com/microservice-architecture-a-brief-overview-and-why-you-should-use-it-in-your-next-project-a17b6e19adfd 我假设现在也存在一种回归到单体架构的趋势,因为在很多情况下,微服务架构有点过头了,而且做好微服务架构设计其实很难。微服务架构有哪些好的实践?在之前的另一篇博文中,我也给出了一些大概,希望对读者有用。 https://towardsdatascience.com/effective-microservices-10-best-practices-c6e4ba0c6ee2 编程语言(整体):Python 将吞噬世界 机器学习、数据分析、数据处理、Web 开发、企业软件开发,甚至是拼接黑洞照片,Python 的影子无处不在。 在著名的编程语言排行榜网站 TIOBE 上,Python 位居最流行编程语言第三位,仅次于 Java 和 C 语言。 更有意思的是,在 2019 年,Python 的流行度翻了一番(从 5% 到 10%)。 Python 的崛起将在 2020 年延续,并缩短与 Java 和 C 语言之间的差距。另一门无所不在的编程语言 JavaScript 正面临下行的风险。为什么 Python 的势头会如此强劲?因为它的入手门槛低,有一个优秀的社区在支持,并受到数据科学家和新生代开发者的喜爱。 编程语言(企业方面):Java 将占主导 之前的 TIOBE 网站截图显示,Java 仍然是一门占主导地位的编程语言,并将在 2020 年继续保持这种地位。JVM 是 Java 的基石,其他编程语言(如 Kotlin、Scala、Clojure、Groovy)也将 JVM 作为运行时。最近,Oracle 修改了 JVM 的许可协议。 新的许可协议意味着使用 Java、Kotlin、Scala 或其他 JVM 编程语言的公司需要向 Oracle 支付大额费用。所幸的是,OpenJDK 让 JVM 继续免费。另外,还有其他一些公司为 JVM 提供企业支持。 因为体积和速度方面的问题,基于 JVM 的编程语言并不适合用在今天的无服务器环境中。Oracle 正在推动 GraalVM 计划,旨在让 Java 变得更加敏捷和快速,让它更适合用在无服务器环境中。因为除了 Java,没有其他编程语言可以提供企业级的稳定性和可靠性,所以 Java 将在 2020 年继续占主导地位。 企业版 Java:Spring 继续发力 曾几何时,在企业开发领域,Spring 和 JavaEE 之间存在着白热化的竞争。但因为 Oracle 在 JavaEE 方面没有作为,在竞争中惨败,这导致了“MicroProfile”计划的形成,并最终促成了 JakartaEE。 虽然所有的政策和活动都是围绕 JavaEE 展开,但 Spring 事实上已经赢得了这场企业 JVM 之争。2020 年,Spring 将成为 JVM 生态系统的头牌。 有两个正在进展中的项目,它们旨在减小 Java 的体积,让它更适合用在无服务器环境中。 其中一个是 Micronaut(https://micronaut.io/)。 另一个是 Quarkus(https://quarkus.io/)。 这两个项目都使用了 GraalVM,它们在 2020 年将会得到 Java 社区更多的关注。 编程语言:后起之秀的突破 2000 年代,编程语言的发展出现了停滞。大多数人认为没有必要再去开发新的编程语言,Java、C 语言、C++、JavaScript 和 Python 已经可以满足所有的需求。但是,谷歌的 Go 语言为新编程语言大门打开了一扇大门。在过去十年出现了很多有趣的编程语言,比如 Rust、Swift、Kotlin、TypeScript。导致这种情况的一个主要原因是已有的编程语言无法充分利用硬件优势(例如多核、更快的网络、云)。另一个原因是现代编程语言更加关注开发者经济,即实现更快速更容易的开发。在 Stackoverflow 提供的一份开发者报告中,排名靠前的现代编程语言如下所示(Rust 连续 4 年名列第一)。 在之前的一篇博文中,我深入探讨了现代编程语言,对比 Rust 和 Go 语言,并说明了为什么现在是采用这些语言的好时机。 https://towardsdatascience.com/back-to-the-metal-top-3-programming-language-to-develop-big-data-frameworks-in-2019-69a44a36a842 最近,微软宣布他们在探索使用 Rust 来开发更安全的软件。 亚马逊最近也宣布要赞助 Rust。 谷歌宣布将 Kotlin 作为 Android 官方开发语言,所以,在 JVM 领域,Kotlin 成了 Java 的主要竞争对手。 Angular 使用 TypeScript 代替 JavaScript,将其作为主要的编程语言,其他 JavaScript 框架(如 React 和 Vue)也开始为 TypeScript 提供更多的支持。 这种趋势将在 2020 年延续下去,很多巨头公司将会深入了解新一代编程语言(如 Rust、Swift、TypeScript、Kotlin),它们会站出来公开表示支持。 Web:JavaScript 继续占主导地位 曾几何时,JavaScript 并不被认为是一门强大的编程语言。在当时,前端内容主要通过后端框架在服务器端进行渲染。2014 年,AngularJS 的出现改变了这种局面。从那个时候开始,更多的 JavaScript 框架开始涌现(Angular 2+、React、Vue、Meteor),JavaScript 已然成为主流的 Web 开发语言。随着 JavaScript 框架不断创新以及微服务架构的崛起,JavaScript 框架在 2020 年将继续主导前端开发。 JavaScript 框架:React 闪耀 虽然 React 是在 AngularJS 之后出现的,但在过去十年对 Web 开发产生了巨大的影响,这也让 Facebook 在与 Google+ 的竞争中打了一场胜战。React 为前端开发带来了一些新的想法,比如事件溯源、虚拟 DOM、单向数据绑定、基于组件的开发,等等。它对开发者社区产生了重大影响,以至于谷歌放弃了 AngularJS,并借鉴 React 的想法推出了彻底重写的 Angular 2+。React 是目前为止最为流行的 JavaScript 框架,下图显示了相关的 NPM 下载统计信息。 为了获得更好的并发和用户体验,Facebook 宣布完全重写 React 的核心算法,推出了 React-Fiber 项目。 2020 年,React 仍然是你开发新项目的首选 Web 框架。其他框架(如 Angular/Angular 2+ 或 Vue)呢?Angular 仍然是一个不错的 Web 开发框架,特别适合企业开发。我敢肯定谷歌在未来几年会在 Angular 上加大投入。Vue 是另一个非常流行的 Web 框架,由中国的巨头公司阿里巴巴提供支持。如果你已经在使用 Angular 或 Vue,就没必要再迁移到 React 了。 App 开发:原生应用 在移动 App 开发方面,有关混合应用开发的炒作有所消停。混合开发提供了更快的开发速度,因为只需要一个开发团队,而不是多个。但原生应用提供了更好的用户体验和性能。另外,混合应用需要经过调整才能使用一些高级特性。对于企业来说,原生应用仍然是首选的解决方案,这种趋势将在 2020 年延续。Airbnb 在一篇博文中非常详细地说明了为什么他们要放弃混合应用开发平台 React Native。 https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a 尽管 Facebook 尝试改进 React Native,谷歌也非常努力地推动混合 App 开发平台 Flutter,但它们仍然只适合用于原型、POC、MVP 或轻量级应用的开发。所以,原生应用在 2020 年仍将继续占主导地位。 在原生应用开发方面,谷歌和苹果分别将 Kotlin 和 Swift 作为各自平台主要的编程语言。谷歌最近再次重申了对 Kotlin 的支持,这对于 Kotlin 用户来说无疑是个好消息。 混合应用开发:React Native 在很多情况下,混合应用是个不错的选择。在这方面也有很多选择:Xamarin、Inoic、React Native 和 Flutter。Facebook 基于成熟的 React 框架推出了 React Native。就像 React 在 Web 框架领域占据主导地位一样,React Native 在混合应用领域也占据着主导地位,如下图所示。 React Native 和 React 有共同的基因,都提供了高度的代码重用性以及“一次开发,到处运行”的能力。React Native 的另一个优势是 Facebook 本身也用它来开发移动应用。谷歌在这个领域起步较晚,但在去年,谷歌的混合应用开发框架 Flutter 获得了不少关注。Flutter 提供了更好的性能,但需要使用另一门不是那么流行的编程语言 Dart。React Native 在 2020 年将继续占主导地位。 API:REST 将占主导地位 REST 是 API 领域事实上的标准,被广泛用在基于 API 的服务间通信上。当然,除了 REST,我们还有其他选择,比如来自谷歌的 gRPC 和来自 Facebook 的 GraphQL。 它们提供了不同的能力。谷歌开发的 gRPC 作为远程过程调用(如 SOAP)的化身,使用 Protobuf 代替 JSON 作为消息格式。Facebook 开发的 GraphQL 作为一个集成层,避免频繁的 REST 调用。gRPC 和 GraphQL 都在各自的领域取得了成功。2020 年,REST 仍然是占主导地位的 API 技术,而 GraphQL 和 gRPC 将作为补充技术。 人工智能:Tensorflow 2.0 将占主导地位 谷歌和 Facebook 也是深度学习 / 神经网络领域的主要玩家。谷歌基于深度学习框架 Theano 推出了 TensorFlow,它很快就成为深度学习 / 神经网络的主要开发库。谷歌还推出了特别设计的 GPU(TPU)来加速 TensorFlow 的计算。 Facebook 在深度学习领域也不甘落后,他们拥有世界上最大的图像和视频数据集合。Facebook 基于另一个深度学习库 Torch 推出了深度学习库 PyTorch。TensorFlow 和 PyTorch 之间有一些区别,前者使用的是静态图进行计算,而 PyTorch 使用的是动态图。使用动态图的好处是可以在运行时纠正自己。另外,PyTorch 对 Python 支持更好,而 Python 是数据科学领域的一门主要编程语言。 随着 PyTorch 变得越来越流行,谷歌也赶紧在 2019 年 10 月推出了 TensorFlow 2.0,也使用了动态图,对 Python 的支持也更好。 2020 年,TensorFlow 2.0 和 PyTorch 将齐头并进。考虑到 TensorFlow 拥有更大的社区,我估计 TensorFlow 2.0 将成为占主导地位的深度学习库。 数据库:SQL是王者,分布式SQL是王后 在炒作 NoSQL 的日子里,人们嘲笑 SQL,还指出了 SQL 的种种不足。有很多文章说 NoSQL 有多么的好,并将要取代 SQL。但等到炒作的潮水褪去,人们很快就意识到,我们的世界不能没有 SQL。以下是最流行的数据库的排名。 可以看到,SQL 数据库占据了前四名。SQL 之所以占主导地位,是因为它提供了 ACID 事务保证,而 ACID 是业务系统最潜在的需求。NoSQL 数据库提供了横向伸缩能力,但代价是不提供 ACID 保证。 互联网公司一直在寻找“大师级数据库”,也就是既能提供 ACID 保证又能像 NoSQL 那样可横向伸缩的数据库。目前有两个解决方案可以部分满足对“大师级数据库”的要求,一个是亚马逊的 Aurora,一个是谷歌的 Spanner。Aurora 提供了几乎所有的 SQL 功能,但不支持横向写伸缩,而 Spanner 提供了横向写伸缩能力,但对 SQL 支持得不好。 2020 年,但愿这两个数据库能够越走越近,或者有人会带来一个“分布式 SQL”数据库。如果真有人做到了,那一定要给他颁发图灵奖。 数据湖:MinIO 将要崛起 现代数据平台非常的复杂。企业一般都会有支持 ACID 事务的 OLTP 数据库(SQL),也会有用于数据分析的 OLAP 数据库(NoSQL)。除此之外,它们还有其他各种数据存储系统,比如用于搜索的 Solr、ElasticSearch,用于计算的 Spark。企业基于数据库构建自己的数据平台,将 OLTP 数据库的数据拷贝到数据湖中。各种类型的数据应用程序(比如 OLAP、搜索)将数据湖作为它们的事实来源。 HDFS 原本是事实上的数据湖,直到亚马逊推出了对象存储 S3。S3 可伸缩,价格便宜,很快就成为很多公司事实上的数据湖。使用 S3 唯一的问题是数据平台被紧紧地绑定在亚马逊的 AWS 云平台上。虽然微软 Azure 推出了 Blob Storage,谷歌也有类似的对象存储,但都不是 S3 的对手。 对于很多公司来说,MinIO 或许是它们的救星。MinIO 是一个开源的对象存储,与 S3 兼容,提供了企业级的支持,并专门为云原生环境而构建,提供了与云无关的数据湖。 微软在 Azure Marketplace 是这么描述 MinIO 的:“为 Azure Blog Storage 服务提供与亚马逊 S3 API 兼容的数据访问”。如果谷歌 GCP 和其他云厂商也提供 MinIO,那么我们将会向多云迈出一大步。 大数据批处理:Spark 将继续闪耀 现如今,企业通常需要基于大规模数据执行计算,所以需要分布式的批处理作业。Hadoop 的 Map-Reduce 是第一个分布式批处理平台,后来 Spark 取代了 Hadoop 的地位,成为真正的批处理之王。Spark 是怎样提供了比 Hadoop 更好的性能的?我之前写了另一篇文章,对现代数据平台进行了深入分析。 https://towardsdatascience.com/programming-language-that-rules-the-data-intensive-big-data-fast-data-frameworks-6cd7d5f754b0 Spark 解决了 Hadoop Map-Reduce 的痛点,它将所有东西放在内存中,而不是在完成每一个昂贵的操作之后把数据保存在存储系统中。尽管 Spark 重度使用 CPU 和 JVM 来执行批处理作业,但这并不妨碍它成为 2020 年批处理框架之王。我希望有人能够使用 Rust 开发出一个更加高效的批处理框架,取代 Spark,并为企业省下大量的云资源费用。 大数据流式处理:Flink 是未来 几年前,实现实时的流式处理几乎是不可能的事情。一些微批次处理框架(比如 Spark Streaming)可以提供“几近”实时的流式处理能力。不过,Flink 改变了这一状况,它提供了实时的流式处理能力。 2019 年之前,Flink 未能得到足够的关注,因为它无法撼动 Spark。直到 2019 年 1 月份,中国巨头公司阿里巴巴收购了 Data Artisan(Flink 背后的公司)。 在 2020 年,企业如果想要进行实时流式处理,Flink 应该是不二之选。不过,跟 Spark 一样,Flink 同样重度依赖 CPU 和 JVM,并且需要使用大量的云资源。 字节码:WebAssembly将被广泛采用 我从 JavaScript 作者 Brandon Eich 的一次访谈中知道了 WebAssembly 这个东西。现代 JavaScript(ES5 之后的版本)是一门优秀的编程语言,但与其他编程语言一样,都有自己的局限性。最大的局限性是 JavaScript 引擎在执行 JavaScript 时需要读取、解析和处理“抽象语法树”。另一个问题是 JavaScript 的单线程模型无法充分利用现代硬件(如多核 CPU 或 GPU)。正因为这些原因,很多计算密集型的应用程序(如游戏、3D 图像)无法运行在浏览器中。 一些公司(由 Mozilla 带领)开发了 WebAssembly,一种底层字节码格式,让任何一门编程语言都可以在浏览器中运行。目前发布的 WebAssembly 版本可以支持 C++、Rust 等。 WebAssembly 让计算密集型应用程序(比如游戏和 AutoCAD)可以在浏览器中运行。不过,WebAssembly 的目标不仅限于此,它还要让应用程序可以在浏览器之外运行。WebAssembly 可以被用在以下这些“浏览器外”的场景中。 移动设备上的混合原生应用。没有冷启动问题的无服务器计算。在服务器端执行不受信任的代码。 我预测,2020 年将是 WebAssembly 取得突破的一年,很多巨头公司(包括云厂商)和社区将会拥抱 WebAssembly。 代码:低代码 / 无代码将更进一步 快速的数字化和工业 4.0 革命意味着软件开发者的供需缺口巨大。由于缺乏开发人员,很多企业无法实现它们的想法。为了降低进入软件开发的门槛,可以尝试无代码(No Code)或低代码(Low Code)软件开发,也就是所谓的 LCNC(Low-Code No-Code)。它已经在 2019 年取得了一些成功。 LCNC 的目标是让没有编程经验的人也能开发软件,只要他们想要实现自己的想法。 虽然我对在正式环境中使用 LCNC 框架仍然心存疑虑,但它为其他公司奠定了良好的基础,像亚马逊和谷歌这样的公司可以基于这个基础构建出有用的产品,就像 AWS Lambda 的蓬勃发展是以谷歌 App Engine 为基础。 2020 年,LCNC 将会获得更多关注。

茶什i 2019-12-26 11:57:03 0 浏览量 回答数 0

问题

Web测试方法

技术小菜鸟 2019-12-01 21:41:32 7022 浏览量 回答数 1

回答

如何掌握牢靠Go语言的容器? 容器相对来说更偏重细节一些,如果想掌握的更牢靠的话呢,还是要多看一下代码,重点给大家几个提示 Go语言的并发初步有哪两个特别重要的特点? **GO语言的协程并发操作或者说协程的资源池,其调度策略有两个: ** 1、没有优先级,没有API能设置优先级,正是因为它一切都是靠Go语言自身的一个调度器来听调度,才能保证它的高效率,这点非常重要。 2、调度的策略是可抢占的,假如说一个任务它长时间的占用CPU,那么它是有可能被购入天的这个调度器给其抢占过来,让其其的任务来做运行,这是两个最重要的特点。 GO语言调度的单元goroutine的应用场景是什么? 使用JAVA或者C编写网络程序时,一个线程来处理一个http请求, 但是对于资源的利用率不高。而Go语言实现了轻量级线程的机制,GO语言在底层封装了所有的系统调用,自己实现了一个调度器,这种设计在操作系统的代码中非常多见。比如现代的操作系统基本都会封装一个软件的Timer,同时可以提供上万个软Timer同时工作,而这只是基于数量很少的硬件timer实现的,而GO语言中的并发也是如此,他是基于线程的调度池,这种调度的单元在Go语言中被称为goroutine。 GO语言与其它并发模型最大的区别是什么? 宏观GO语言与其它并发模型最大的不同,就是其推荐使用通信的这种方式来替代共享内存。当资源需要在goroutine之间进行共享的时候,实际上就是这个资源,或者说这个信息通过通道在goroutine之间进行通信的过程。因为这个锁,一般来说都是用在这个共享内存当中的,因为如果说大家阅读GO语言的相关代码,就可以看到这个channel,它实际上是基于锁来保证并发安全。 然而,这也不代表GO语言当中只能使用channel来进行一些操作,其也具备锁这方面的知识。因为现实当中,这个锁还是有一定它现实的意义和现实的要求,因为这个锁它最关键的一个意义就是它能保证资源能在并发的操作当中有一个合理的调度情况和调度策略。其中跟这个最重要,或者说最关联性最强的一个概念就是原子操作。 GO语言中的原子操作具体实现过程是怎样的? 对于原子操作,在其逻辑下,按照它书面的定义上来讲,是指不会被调度器打断的操作。对原子操作实际上就是不存在中间状态的一种操作,要不就全成功,要不全失败,这个在我们在用并发方式来调动某任务,或者说来设计某种并发系统的情况下,这种名字操作我发现是非常重要的设计理念之一。 并发与并行具体概念及实际区分是怎样的? 有一个比较重要的一个概念,就是并发与并行,其实并发与并行,它实际上具体的含义是不一样的,并发实际上是把任务在不同的时间点交给同样一个处理器来进行处理,在同一个时间点,任务不会同时进行,只是任务感觉自己正在执行,因为其那会儿可能正在堵塞状态或者说是就绪状态,其不知道自己被暂停了,以为已经被调度走了,可能自己没有感知,但是实际上CPU所有权已经不在这个任务身上了。 并行比并发更高级一些,它实际上是把每个任务都交给独立的处理器去进行完成,但同一时间点,任务在一定程度上实际上是同时在执行的。一般来说,并发的性能是要比并行更重要一些,在1.5版本之前,我们需要人工去设置GO调度器最多能运行在多少个CPU上,但是在最新的GO版本当中,已经不需要这个相关的操作。 详细介绍一下并发程序中的竞争态? 并发系统设计最初始的这一个概念就是并发程序设计当中一个竞合的概念,或者也叫竞争态。假如说我要记录一个文件的阅读量,但是这个文件或者说这个网页,可能它的阅读渠道有非常多,有可能通过引擎通过微信通过APP等等这些渠道,这些渠道的话呢,它的阅读也都是并发的,这就会涉及到同样一个变量,被多个协程的所共同访问的情况。具体代码如下: 对于GO语言并发体系中的主推的通信机制是什么? channel是GO语言并发体系中的主推的通信机制,它可以让一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个特殊的类型,也就是 channels 可发送数据的类型。一个可以发送 int 类型数据的 channel 一般写为 chan int。 GO语言当中,它实际上是大家协同的机制,通过这种方式让几个goroutine之间做达到一个协调的效果,那么每个goroutine当中,实际上channel都是一个特殊的类型,它实际上是可以发送数据。比如现在想发送一个int类型的数据,那么channel就要定义一个发送int数据的一个管道。 那么GO语言当中,提倡使用通讯的方式来代替共享内存的方式来做goroutine,或者说并发之间的一个协同。channel如果我们后续阅读它的代码就会知道,它是保证协程安全,并且它遵循这个先入先出的原则来让这个储蓄方读取获得数据,而且它能保证顺序,正是这两个特性,可以让这个channel替代共享内存,因为它的如果顺序有所改变的话,它实际上也是有会有问题。 详细介绍GO语言中关于通道的声明涉及哪些方面? 1.经典方式声明 通过使用chan类型,其声明方式如下: var name chan type 其中type表示通道内的数据类型;name:通道的变量名称,不过这样创建的通道只是空值 nil,一般来说都是通道都是通过make函数创建的。 2.make方式 make函数可以创建通道格式如下: name := make(chan type) 3.创建带有缓冲的通道 后面会讲到缓冲通道的概念,这里先说他的定义方式 name := make(chan type, size) 其中type表示通道内的数据类型;name:通道的变量名称,size代表缓冲的长度。 具体介绍通道数据收发的详细过程有哪些? 通道的数据发送 通道当中发送数据的操作服务是这样的这样的一个大于号加上一个减号。 chan <- value 注意,如果是发送给一个没有缓冲的一个通道。假如说数据没有被接收的话,那么这个发送操作将持续被注册,也就是说就是channel这个语句就直接被注册到这,假如说没有任何的协程去读到他或者其他语句去读到这个产品,那么这个语句就被注册掉了。但GO语言是能发现的,如果其一直在堵塞的话,那实际上就造成死锁,GO语言的编译器实际上能发现的有点错误。 假如说,首先创建一个int型的通道,然后直接尝试发送一个数据给它,编译会报错,然后呢,数据的这个数据的接收的话,实际上就是把这个点号的位置跟那个大于号的位置做了一个调换。其实把这个双方的位置做了一个调换之后,是实际上就是都做了一个允许的操作。这其中的话呢,还有一种比较特殊的一个读取操作是其可以忽略到接收到的数据,因为不管管道中发出的数据,如果没读的话就堵塞到这,那么如果你觉得这个语句你也不需要,那么你可以把那个变量给它忽略掉。 2.通道的数据接收 通道接收数据的操作符也是<-,具体有以下几种方式 - 1) 阻塞接收数据 阻塞模式接收数据时,将接收变量作为<-操作符的左值,格式如下: data := <-ch 执行该语句时将会阻塞,直到接收到数据并赋值给 data 变量。 如需要忽略接收的数据,则将data变量省略,具体格式如下: <-ch - 2) 非阻塞接收数据 使用非阻塞方式从通道接收数据时,语句不会发生阻塞,格式如下: data, ok := <-ch 非阻塞的通道接收方法可能造成高的 CPU 占用,因此使用非常少。一般只配合select语句配合定时器做超时检测时使用。 关于通道数据收发有哪些需要注意的事项? 通道数据在进行输入收发的时候,必须要在两个不同的goroutine当中进行,因在同一个goroutine当中,收发的这些语句实际上都是堵塞的,你可能在同一个goroutine当中,它的这个函数已经在那边阻塞住了,或者说程序已经在那边阻塞住了,它已经停在那了,你后面有一句你能执行不到,所以说通道的收发必须在两个不同的goroutine之间来进行,在同一个goroutine之间的这个收发操作的话,实际上是没有意义的。 接收将持续堵塞,直到发送方发送出去,如果接收方接收,然后通道中没有发送方数据时,接收方也会发送,直到发送方到发送数据为止。就是刚才说的这个一体两面,这个发送方假如说没有人读的话,发送方会堵塞,假如说没有人写的话,那么接收方也会发生堵塞,这两边实际上都会有一个堵塞的情况。那么这个通道的收发的话呢,一般来说一次只能收一一个元素,假如说这个是一个有缓冲的一个通道,我通过一次不操作的话,实际上也只不过读出一个元素。不能把它一些缓冲区所有元素都读出来。 聊一下生产者消费者模式具体内容有哪些? 介绍一下生产者消费者模式,从GO语言的这个并发模型来看,也就是说假如说咱们站在一个比较高的一个高度来看,其实利用channel的确能达到共享内存的目的。这个channel的性质与在读写状态且保证顺序的共享内存并无不同。甚至我们可以说这个是基于消息队列的封装程度可以比共享内存来的更安全,所以说呢,这个在这个GO语言当中,或者说在GO语言的这个设计风格当中的话呢,其这个生产者消费者模式实现起来会相对来说比较简单一些。我们先介绍一下什么是生产者消费者。 就这个这这张图当中的话呢,就是一个典型的那种消费的问题, 就是说我是生产者的话我会生产一些产品,然后放到这个仓库当中,消费者的话会从那个仓库当中去取商品,这个可以说是消息队列,还有包括卡夫卡那些比较经典的相应队列当中,都会用到的这么一个设计模式,或者说其们从本质上来说的话,都是基于这样一个设计模式,交易的生产者是谁?消费者是谁?这个消息队列的话是。这个生产者消费者模式的话呢,实际上也成为有缓冲有限缓冲问题,它是一个并发的一个经典的案例,因为我们知道这个商品仓库的库房大小是有限的,也就是说生产者不能无限的去生产商品,一旦这个库房爆掉的话,它是它是必须要中止自己的生产,消费者也是不能无限地获取消息。 假如仓库是空的话,那这个消费者的这个相关的情况也需要被阻塞。那么怎么在这个生产者跟消费者之间保证商品不丢失。这就是生产者与消费者之间最核心的内容。先来看一下这个Java当中生产者消费者的这种实现到底是什么样的。这个可以说是一个最经典的这么样一个实现。这个Java当中是没有channel,那么它只能通过什么呢,只能通过信号量和一个一个log,也就是说一个忽视服务态度,这两个这两个配合信号量和所配合才能共同完成,这样一个生产者消费者这么一个相关的工作。 GO语言并发实战详细过程梳理 在现在这个远程办公的这一个大的背景下,积累了大量重复的文件,因为很可能大家都不断的在不同的群里发相同的文件,发相同的这个报表,以及一些相同的视频等等这些需要学习的材料,那么怎么把这些文件都找出来,然后把这些相同文件都给删掉了,这实际上是并发课的一个实践的一个内容,因为这个创业型的这个方案的话,它的代码相对来说比较长。 如何使用GO语言清理PC机中的文件,详细代码及注释如下: package main import ( // "fmt" // fmt 包使用函数实现 I/O 格式化(类似于 C 的 printf 和 scanf 的函数), 格式化参数源自C,但更简单 "io/ioutil" //"sync" //"time" ) func PrintRepreatFile(path string, fileNameSizeMap map[string]int64, exFileList []string) { fs, _ := ioutil.ReadDir(path) for _, file := range fs { if file.IsDir() { PrintRepreatFile(path+"/"+file.Name(), fileNameSizeMap, exFileList)//遍历整个文件系统,如果是目录则递归调用 } else { if file.Size() > 1000000 {//设定文件清理阈值,如果大于一定大小再进行清理 fileSize := fileNameSizeMap[file.Name()]//通过查哈希表的方式来确定,有无重名且大小相同的文件。 if fileSize == file.Size() { fmt.Println(path + "/" + file.Name())//如果有则打印出来 exFileList = append(exFileList, path+file.Name())//将结果记入切片当中 } else { fileNameSizeMap[file.Name()] = file.Size() } } } } } func main() { //方式一 fileNameSizeMap := make(map[string]int64, 10000) exFileList := make([]string, 100, 1000) PrintRepreatFile("E:/test", fileNameSizeMap, exFileList) } 这个程序在GO语言的环境下可以直接运行使用,其中有几个知识点,也是咱们前文提到过的,首先是切片的大小一定要设定的相对合适一些,如果容量不够大造成频繁扩容非常浪费资源。二是哈希表也就是map没有并发安全的属于,在我们这个未引入并发的程序中可以使用,如果有并发操作,那么map不再适用了。 可能很多人被GO语言的在并发性能所吸引入坑的,GO语言之父也就是UNIX之父Ken Thompson明显给出了很多建议,根据笔者在操作系统方面的相关经验来看,GO语言设计中经常参考UNIX内核的设计思路。比如硬定时器的数量有限,无法满足系统实际运行需要,所以在内核代码中就会看到基于硬件定时器的软件定时器的方案,而软件定时器的数量可以比硬件定时器多几百倍。 这样的理念明显融合到了 goroutine之中,由于其它编程语言往往直接通过系统级别的线程来实现并发功能,但是这样的方式往往会是大马拉小车,造成系统资源的浪费。因此GO语言封装了所有的系统操作,实现了更加轻量级的协程-goroutine。只要使用关键字(go)就可以启动协程,对比C++、JAVA的多线程并发模型,GO的协程更简单明了。 当然协程之间的消息通信与并发控制也是非常重要的一环。在GO语言借鉴了Message Queue的消息队列机制替代共享内存的方式进行协程间通信,其中管道channel作为基本的数据类型,保证并发时的操作安全。而且管道的引入还带来很多实践中非常实用的功能,比如可以方便实现生产者、消费者等并发设计模式,而这些设计模式在其它使用共享存内存的并发模型中实现起相关功能来非常的繁锁。 在GO语言中在调用函数前加入go 关键字,就能启动一个协程,也就是一个并发,但是我们上面的程序如果把调用方式改为: go PrintRepreatFile("E:/test", fileNameSizeMap, exFileList) 你会发现程序会直接退出,什么都没做,所以GO语言的并发对于初学者来说还是有一定门槛的,比如上例中如果想设计成一个并行的程序,如何让多个协程共同来帮忙找出重复的文件其实还是要费一番周折的。

剑曼红尘 2020-04-13 11:06:46 0 浏览量 回答数 0

问题

荆门开诊断证明-scc

游客5k2abgdj3m2ti 2019-12-01 22:09:00 1 浏览量 回答数 0

回答

怎么 没人来呀 @中山野鬼###### 1、如果想去掉while(true),可以考虑通知实现; 2、关于自动重连的问题,可以考虑重发送逻辑中抽离出来,采用心跳检测完成; 3、另外发送速率统计部分也应该抽离出来。 4、上多通道要考虑资源使用可控。 5、实在不行按照业务拆分成多模块,用redis 或mq类的扩展一下架构设计; ######回复 @OS小小小 : map =(Map)JSONObject.parse(SendMsgCMPP2ThredPoolByDB.ZhangYi.take()); 换成take,阻塞线程,试试。######回复 @OS小小小 : 1、通知只是告知队列里有新的数据需要处理了; 5、内存队列换成redis队列 实现成本增加,但是可扩展性增加;######1、通知实现的话 ,岂不是 无法保证 最少发送么,又会陷入另一个问题中 是吗? 或者是我的想法不对么? 2、嗯,这一块可以这样做。谢谢你 3、速率统计这里 我目前想不到怎么抽离、既可以控制到位,又可以保证不影响。。。 5、redis 是有的 但是 redis的队列的话 跟我这个 没啥区别吧,可能速度更快一点。######while(true) 里面 没数据最起码要休眠啊,不停死循环操作,又没有休眠cpu不高才怪######回复 @OS小小小 : 休眠是必须的,只是前面有数据进来,可以用wait notify 的思路通知,思路就是这样,CountDownLatch 之类多线程通讯也可以实现有数据来就能立即处理的功能######嗯,目前在测试 排除没有数据的情况,所以这一块没有去让他休眠,后面会加进去。 就针对于目前这种情况,有啥好办法吗###### 我的思路是:一个主线程,多个任务子线程。 主线程有一层while(true),这个循环是不断的扫描LinkedBlockingQueue是否有数据,有则交个任务子线程(也就是你这里定义的线程池)处理,而不是像你这样每个子任务线程都有一个while(true) ######这才是对的做法######嗯,这思路可以。谢谢哈###### 引用来自“K袁”的评论 我的思路是:一个主线程,多个任务子线程。 主线程有一层while(true),这个循环是不断的扫描LinkedBlockingQueue是否有数据,有则交个任务子线程(也就是你这里定义的线程池)处理,而不是像你这样每个子任务线程都有一个while(true) 正确做法. 还有就是 LinkedBlockingQueue 本身阻塞的,while(true)没问题,主要在于不需要每个发送线程都去block######while(true)不加休眠就会这样###### java 的线程数量大致要和cpu数量一致,并不是越多越快,线程调度是很消耗时间的。要用好多线程,就需要设计出好的多线程业务模型,不恰当的sleep和block是性能的噩梦。利用好LinkedBlockingQueue,队列空闲时读队列的线程会释放cpu。利用消息触发后续线程工作,就没必要使用while(true)来不停的扫描。 ######@蓝水晶飞机 看到你要比牛逼,我就没有兴趣跟你说话了######回复 @不日小鸡 : 我就是装逼怎么啦,特么的装逼装出样子来的,起码也比你牛逼啊。######回复 @蓝水晶飞机 : 你说这话不能掩盖你没有回复我的问题又来回复我导致装逼失败的事实。 那你不是楼主你回复我干什么,还不是回答我的问题。 不要装逼了好么,装多就成傻逼了######回复 @不日小鸡 : 此贴楼主不是你,装什么逼。######回复 @王斌_ : 这些我都知道,我的意思是你这样回复可能会误导其他看帖子的人或者新手,让他们以为线程数就等于CPU数###### 引用来自“OS小小小”的评论 怎么 没人来呀 @中山野鬼 抬举我了。c++ 我还敢对不知深浅的人说,“权当我不懂”,java真心只是学过,没有实际工程上的经验。哈。而且我是c的思维,面对c适合的应用开发,是反对使用线程的。基本思维是,执行模块的生命周期不以任务为决定,同类的执行模块,可根据物理硬核数量,形成对应独立多个进程,但绝对不会同类的任务独立对应多个线程。哈。所以java这类面向线程的设计,没办法参与讨论。设计应用目标不同,系统组织策略自然有异。 唯一的建议是:永远不要依赖工具,特别是所谓的垃圾资源处理回收机制,无论它做的再好,一旦你依赖,必然你的代码,在不久的将来会因为系统设计规模的变大,而变的垃圾。哈。 听不懂的随便喷,希望听懂的,能记得这个观点,这不是我一个人的观点。 ######给100万像素做插值运算进行染色特效,请问单线程怎么做比多线程快?###### @乌龟壳 : 几种方法都可以,第一是按照计算步骤,每个进程处理一个步骤,然后切换共享空间(这没有数据传递逻辑上的额外开销),就是流水思维。第二个是block的思维,同样的几个进程负责相同计算,但负责不同片区。同时存在另一类的进程是对前期并发处理完的工作进行边界处理。 你这个例子体现不出进程和线程的差异的。 如果非要考虑进程和线程在片内cache的差异,如果没记错(错了大家纠正哈),进程之间的共享是在二级缓存之间吧。即便线程能做到一级缓存之间的共享,但对于这种大批量像素的计算,用进程仍然是使用 dma,将数据成块载入一级缓存区域进行处理,而这个载入工作和计算工作是同步的。不会有额外太多的延迟。 你举的这个例子,还真好是我以前的老本行。再说了。像素计算,如今都用专用计算处理器了吧。还用x86或arm来处理,不累死啊。哈。 而且这种东西java不适合,同样的处理器,用c写,基本可以比java快1到2倍。因为c可以直接根据硬件特性和计算逻辑特点有效调度底层硬件驱动方式。而java即便你用了底层优化的官方库,仍然不能保证硬件与计算目标特性的高度整合。 ######回复 @中山野鬼 : 简单来说,你的多个进程处理结果进行汇总的时候,是不是要做内存复制操作?如果是多线程天然就不用,多进程用系统的共享内存机制也不用,问题是既然用了共享内存,和多线程就没区别了。######回复 @乌龟壳 : 两回事哦。共享空间是独立的,而线程如果我没记错,全局变量,包括文件内的(静态变量)是共享的。不同线程共享同一个进程内的变量嘛。这些和业务逻辑相关的东西,每个线程又是独立一套业务逻辑,针对c语言,这样去设计,不是没事找事嘛。面向对象语言,这块都帮你处理好了,自然没有关系。######既然有共享空间了,那你所说的进程和线程实际就是一回事了。###### @乌龟壳   ,数据分两种,一种和算法或处理相关的。一种是待处理的数据。 前者,不应该共享,后者属于数据加工流程,必然存在数据传递或流动,最低成本的传递/流动方式就是共享内存,交替使用权限的思路。 但这仅仅针对待加工的数据和辅助信息,而不针对程序本身。 进程不会搞混乱这些东西特别是(待加工数据的辅助信息),而线程,就各种乱吧。哈。 进程之间,虽然用共享空间,但它本质是数据传递/流动,当你采用多机(物理机器)并发处理时,进程移动到另外一个物理主机,则共享空间就是不能选择的传递/流动方式了。但线程就没有这些概念。 ######回复 @中山野鬼 : 是啊,java天然就不是像C一样对汇编的包装。######@乌龟壳 面向企业级的各种业务,java这些没问题的。而且更有优势,面向计算设备特性的设计开发,就不行了。哈。######回复 @中山野鬼 : 也算各有场景吧,java同样可以多进程可以分布式来降低多线程的风险。java也可以静态编译成目标机器码。总之事在人为。######回复 @乌龟壳 : 高手,啥都可以,低手,依赖这些,就是各种想当然。哈哈。######回复 @中山野鬼 : 那针对java的垃圾回收,这个东西是可以调节它算法的,不算依赖工具吧,哈。不然依赖C语言语法也算依赖工具咯。哈。;-p

kun坤 2020-05-31 13:04:51 0 浏览量 回答数 0

回答

从业余程序员到职业程序员 程序员刚入行时,我觉得最重要的是把自己培养成职业的程序员。 我的程序员起步比同龄人都晚了很多,更不用说现在的年轻人了。我大学读的是生物专业,在上大学前基本算是完全没接触过计算机。军训的时候因为很无聊,我和室友每天跑去学校的机房玩,我现在还印象很深刻,我第一次走进机房的时候,别人问,你是要玩windows,还是dos,我那是完全的一抹黑。后来就只记得在机房一堆人都是在练习盲打,军训完,盲打倒是练的差不多了,对计算机就这么产生了浓厚的兴趣,大一的时候都是玩组装机,捣鼓了一些,对计算机的硬件有了那么一些了解。 到大二后,买了一些书开始学习当时最火的网页三剑客,学会了手写HTML、PS的基本玩法之类的,课余、暑假也能开始给人做做网站什么的(那个时候做网站真的好赚钱),可能那样过了个一年左右,做静态的网页就不好赚钱了,也不好找实习工作,于是就开始学asp,写些简单的CRUD,做做留言板、论坛这些动态程序,应该算是在这个阶段接触编程了。 毕业后加入了深圳的一家做政府行业软件的公司,一个非常靠谱和给我空间的Leader,使得自己在那几年有了不错的成长,终于成了一个职业的程序员。 通常来说,业余或半职业的程序员,多数是1个人,或者很小的一个团队一起开发,使得在开发流程、协作工具(例如jira、cvs/svn/git等)、测试上通常会有很大的欠缺,而职业的程序员在这方面则会专业很多。另外,通常职业的程序员做的系统都要运行较长的时间,所以在可维护性上会特别注意,这点我是在加入阿里后理解更深的。一个运行10年的系统,和一个写来玩玩的系统显然是有非常大差别的。 这块自己感觉也很难讲清楚,只能说模模糊糊有个这样的概念。通常在有兴趣的基础上,从业余程序员跨越到成为职业程序员我觉得不会太难。 编程能力的成长 作为程序员,最重要的能力始终是编程能力,就我自己的感受而言,我觉得编程能力的成长主要有这么几个部分: 1、编程能力初级:会用 编程,首先都是从学习编程语言的基本知识学起的,不论是什么编程语言,有很多共同的基本知识,例如怎么写第一个Hello World、if/while/for、变量等,因此我比较建议在刚刚开始学一门编程语言的时候,看看编程语言自己的一些文档就好,不要上来就去看一些高阶的书。我当年学Java的时候上来就看Think in Java、Effective Java之类的,真心好难懂。 除了看文档以外,编程是个超级实践的活,所以一定要多写代码,只有这样才能真正熟练起来。这也是为什么我还是觉得在面试的时候让面试者手写代码是很重要的,这个过程是非常容易判断写代码的熟悉程度的。很多人会说由于写代码都是高度依赖IDE的,导致手写很难,但我绝对相信写代码写了很多的人,手写一段不太复杂的、可运行的代码是不难的。即使像我这种三年多没写过代码的人,让我现在手写一段不太复杂的可运行的Java程序,还是没问题的,前面N年的写代码生涯使得很多东西已经深入骨髓了。 我觉得编程能力初级这个阶段对于大部分程序员来说都不会是问题,勤学苦练,是这个阶段的核心。 2、编程能力中级:会查和避免问题 除了初级要掌握的会熟练的使用编程语言去解决问题外,中级我觉得首先是提升查问题的能力。 在写代码的过程中,出问题是非常正常的,怎么去有效且高效的排查问题,是程序员群体中通常能感受到的大家在编程能力上最大的差距。 解决问题能力强的基本很容易在程序员群体里得到很高的认可。在查问题的能力上,首先要掌握的是一些基本的调试技巧,好用的调试工具,在Java里有JDK自带的jstat、jmap、jinfo,不在JDK里的有mat、gperf、btrace等。工欲善其事必先利其器,在查问题上是非常典型的,有些时候大家在查问题时的能力差距,有可能仅仅是因为别人比你多知道一个工具而已。 除了调试技巧和工具外,查问题的更高境界就是懂原理。一个懂原理的程序员在查问题的水平上和其他程序员是有明显差距的。我想很多的同学应该能感受到,有些时候查出问题的原因仅仅是因为有效的工具,知其然不知其所以然。 我给很多阿里的同学培训过Java排查问题的方法,在这个培训里,我经常也会讲到查问题的能力的培养最主要的也是熟练,多尝试给自己写一些会出问题的程序,多积极的看别人是怎么查问题的,多积极的去参与排查问题,很多最后查问题能力强的人多数仅仅是因为“无他,但手熟尔”。 我自己排查问题能力的提升主要是在2009年和2010年。那两年作为淘宝消防队(处理各种问题和故障的虚拟团队)的成员,处理了很多的故障和问题。当时消防队还有阿里最公认的技术大神——多隆,我向他学习到了很多排查问题的技巧。和他比,我排查问题的能力就是初级的那种。 印象最深刻的是一次我们一起查一个应用cpu us高的问题,我们两定位到是一段代码在某种输入参数的时候会造成cpu us高的原因后,我能想到的继续查的方法是去生产环境抓输入参数,然后再用参数来本地debug看是什么原因。但多隆在看了一会那段代码后,给了我一个输入参数,我拿这个参数一运行,果然cpu us很高!这种case不是一次两次。所以我经常和别人说,我是需要有问题场景才能排查出问题的,但多隆是完全有可能直接看代码就能看出问题的,这是本质的差距。 除了查问题外,更厉害的程序员是在写代码的过程就会很好的去避免问题。大家最容易理解的就是在写代码时处理各种异常情况,这里通常也是造成程序员们之间很大的差距的地方。 写一段正向逻辑的代码,大部分情况下即使有差距,也不会太大,但在怎么很好的处理这个过程中有可能出现的异常上,这个时候的功力差距会非常明显。很多时候一段代码里处理异常逻辑的部分都会超过正常逻辑的代码量。 我经常说,一个优秀程序员和普通程序员的差距,很多时候压根就不需要看什么满天飞的架构图,而只用show一小段的代码就可以。 举一个小case大家感受下。当年有一个严重故障,最后查出的原因是输入的参数里有一个是数组,把这个数组里的值作为参数去查数据库,结果前面输入了一个很大的数组,导致从数据库查了大量的数据,内存溢出了,很多程序员现在看都会明白对入参、出参的保护check,但类似这样的case我真的碰到了很多。 在中级这个阶段,我会推荐大家尽可能的多刻意的去培养下自己这两个方面的能力,成为一个能写出高质量代码、有效排查问题的优秀程序员。 3、编程能力高级:懂高级API和原理 就我自己的经历而言,我是在写了多年的Java代码后,才开始真正更细致的学习和掌握Java的一些更高级的API,我相信多数Java程序员也是如此。 我算是从2003年开始用Java写商业系统的代码,但直到在2007年加入淘宝后,才开始非常认真地学习Java的IO通信、并发这些部分的API。尽管以前也学过也写过一些这样的代码,但完全就是皮毛。当然,这些通常来说有很大部分的原因会是工作的相关性,多数的写业务系统的程序员可能基本就不需要用到这些,所以导致会很难懂这些相对高级一些的API,但这些API对真正的理解一门编程语言,我觉得至关重要。 在之前的程序员成长路线的文章里我也讲到了这个部分,在没有场景的情况下,只能靠自己去创造场景来学习好。我觉得只要有足够的兴趣,这个问题还是不大的,毕竟现在有各种开源,这些是可以非常好的帮助自己创造机会学习的,例如学Java NIO,可以自己基于NIO包一个框架,然后对比Netty,看看哪些写的是不如Netty的,这样会非常有助于真正的理解。 在学习高级API的过程中,以及排查问题的过程中,我自己越来越明白懂编程语言的运行原理是非常重要的,因此我到了后面的阶段开始学习Java的编译机制、内存管理、线程机制等。对于我这种非科班出身的而言,学这些会因为缺乏基础更难很多,但这些更原理性的东西学会了后,对自己的编程能力会有质的提升,包括以后学习其他编程语言的能力,学这些原理最好的方法我觉得是先看看一些讲相关知识的书,然后去翻看源码,这样才能真正的更好的掌握,最后是在以后写代码的过程中、查问题的过程中多结合掌握的原理,才能做到即使在N年后也不会忘。 在编程能力的成长上,我觉得没什么捷径。我非常赞同1万小时理论,在中级、高级阶段,如果有人指点或和优秀的程序员们共事,会好非常多。不过我觉得这个和读书也有点像,到了一定阶段后(例如高中),天分会成为最重要的分水岭,不过就和大部分行业一样,大部分的情况下都还没到拼天分的时候,只需要拼勤奋就好。 系统设计能力的成长 除了少数程序员会进入专深的领域,例如Linux Kernel、JVM,其他多数的程序员除了编程能力的成长外,也会越来越需要在系统设计能力上成长。 通常一个编程能力不错的程序员,在一定阶段后就会开始承担一个模块的工作,进而承担一个子系统、系统、跨多领域的更大系统等。 我自己在工作的第三年开始承担一个流程引擎的设计和实现工作,一个不算小的系统,并且也是当时那个项目里的核心部分。那个阶段我学会了一些系统设计的基本知识,例如需要想清楚整个系统的目标、模块的划分和职责、关键的对象设计等,而不是上来就开始写代码。但那个时候由于我是一个人写整个系统,所以其实对设计的感觉并还没有那么强力的感觉。 在那之后的几年也负责过一些系统,但总体感觉好像在系统设计上的成长没那么多,直到在阿里的经历,在系统设计上才有了越来越多的体会。(点击文末阅读原文,查看:我在系统设计上犯过的14个错,可以看到我走的一堆的弯路)。 在阿里有一次做分享,讲到我在系统设计能力方面的成长,主要是因为三段经历,负责专业领域系统的设计 -> 负责跨专业领域的专业系统的设计 -> 负责阿里电商系统架构级改造的设计。 第一段经历,是我负责HSF。HSF是一个从0开始打造的系统,它主要是作为支撑服务化的框架,是个非常专业领域的系统,放在整个淘宝电商的大系统来看,其实它就是一个很小的子系统,这段经历里让我最深刻的有三点: 1).要设计好这种非常专业领域的系统,专业的知识深度是非常重要的。我在最早设计HSF的几个框的时候,是没有设计好服务消费者/提供者要怎么和现有框架结合的,在设计负载均衡这个部分也反复了几次,这个主要是因为自己当时对这个领域掌握不深的原因造成的; 2). 太技术化。在HSF的阶段,出于情怀,在有一个版本里投入了非常大的精力去引进OSGi以及去做动态化,这个后来事实证明是个非常非常错误的决定,从这个点我才真正明白在设计系统时一定要想清楚目标,而目标很重要的是和公司发展阶段结合; 3). 可持续性。作为一个要在生产环境持续运行很多年的系统而言,怎么样让其在未来更可持续的发展,这个对设计阶段来说至关重要。这里最low的例子是最早设计HSF协议的时候,协议头里竟然没有版本号,导致后来升级都特别复杂;最典型的例子是HSF在早期缺乏了缺乏了服务Tracing这方面的设计,导致后面发现了这个地方非常重要后,全部落地花了长达几年的时间;又例如HSF早期缺乏Filter Chain的设计,导致很多扩展、定制化做起来非常不方便。 第二段经历,是做T4。T4是基于LXC的阿里的容器,它和HSF的不同是,它其实是一个跨多领域的系统,包括了单机上的容器引擎,容器管理系统,容器管理系统对外提供API,其他系统或用户通过这个来管理容器。这个系统发展过程也是各种犯错,犯错的主要原因也是因为领域掌握不深。在做T4的日子里,学会到的最重要的是怎么去设计这种跨多个专业领域的系统,怎么更好的划分模块的职责,设计交互逻辑,这段经历对我自己更为重要的意义是我有了做更大一些系统的架构的信心。 第三段经历,是做阿里电商的异地多活。这对我来说是真正的去做一个巨大系统的架构师,尽管我以前做HSF的时候参与了淘宝电商2.0-3.0的重大技术改造,但参与和自己主导是有很大区别的,这个架构改造涉及到了阿里电商众多不同专业领域的技术团队。在这个阶段,我学会的最主要的: 1). 子系统职责划分。在这种超大的技术方案中,很容易出现某些部分的职责重叠和冲突,这个时候怎么去划分子系统,就非常重要了。作为大架构师,这个时候要从团队的职责、团队的可持续性上去选择团队; 2). 大架构师最主要的职责是控制系统风险。对于这种超大系统,一定是多个专业领域的架构师和大架构师共同设计,怎么确保在执行的过程中对于系统而言最重要的风险能够被控制住,这是我真正的理解什么叫系统设计文档里设计原则的部分。 设计原则我自己觉得就是用来确保各个子系统在设计时都会遵循和考虑的,一定不能是虚的东西,例如在异地多活架构里,最重要的是如何控制数据风险,这个需要在原则里写上,最基本的原则是可接受系统不可用,但也要保障数据一致,而我看过更多的系统设计里设计原则只是写写的,或者千篇一律的,设计原则切实的体现了架构师对目标的理解(例如当时异地多活这个其实开始只是个概念,但做到什么程度才叫做到异地多活,这是需要解读的,也要确保在技术层面的设计上是达到了目标的),技术方案层面上的选择原则,并确保在细节的设计方案里有对于设计原则的承接以及执行; 3). 考虑问题的全面性。像异地多活这种大架构改造,涉及业务层面、各种基础技术层面、基础设施层面,对于执行节奏的决定要综合考虑人力投入、机器成本、基础设施布局诉求、稳定性控制等,这会比只是做一个小的系统的设计复杂非常多。 系统设计能力的成长,我自己觉得最重要的一是先在一两个技术领域做到专业,然后尽量扩大自己的知识广度。例如除了自己的代码部分外,还应该知道具体是怎么部署的,部署到哪去了,部署的环境具体是怎么样的,和整个系统的关系是什么样的。 像我自己,是在加入基础设施团队后才更加明白有些时候软件上做的一个决策,会导致基础设施上巨大的硬件、网络或机房的投入,但其实有可能只需要在软件上做些调整就可以避免,做做研发、做做运维可能是比较好的把知识广度扩大的方法。 第二点是练习自己做tradeoff的能力,这个比较难,做tradeoff这事需要综合各种因素做选择,但这也是所有的架构师最关键的,可以回头反思下自己在做各种系统设计时做出的tradeoff是什么。这个最好是亲身经历,听一些有经验的架构师分享他们选择背后的逻辑也会很有帮助,尤其是如果恰好你也在同样的挑战阶段,光听最终的架构结果其实大多数时候帮助有限。 技术Leader我觉得最好是能在架构师的基础上,后续注重成长的方面还是有挺大差别,就不在这篇里写了,后面再专门来写一篇。 程序员金字塔 我认为程序员的价值关键体现在作品上,被打上作品标签是一种很大的荣幸,作品影响程度的大小我觉得决定了金字塔的层次,所以我会这么去理解程序员的金字塔。 当然,要打造一款作品,仅有上面的两点能力是不够的,作品里很重要的一点是对业务、技术趋势的判断。 希望作为程序员的大伙,都能有机会打造一款世界级的作品,去为技术圈的发展做出贡献。 由于目前IT技术更新速度还是很快的,程序员这个行当是特别需要学习能力的。我一直认为,只有对程序员这个职业真正的充满兴趣,保持自驱,才有可能在这个职业上做好,否则的话是很容易淘汰的。 作者简介: 毕玄,2007年加入阿里,十多年来主要从事在软件基础设施领域,先后负责阿里的服务框架、Hbase、Sigma、异地多活等重大的基础技术产品和整体架构改造。

茶什i 2020-01-10 15:19:35 0 浏览量 回答数 0

问题

Swift2.0到底「新」在哪?

忆远0711 2019-12-01 21:30:17 8367 浏览量 回答数 0

回答

1,架构师是什么?要想往架构师的方向发展首先要知道架构师是什么?架构师是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。一个架构师得需要足够的想像力,能把各种目标需求进行不同维度的扩展,为目标客户提供更为全面的需求清单。架构师在软件开发的整个过程中起着很重要的作用。说的详细一些,架构师就是确认和评估系统需求,给出开发规范,搭建系统实现的核心构架,并澄清技术细节、扫清主要难点的技术人员。主要着眼于系统的“技术实现”。2,架构师的任务架构师的主要任务不是从事具体的软件程序的编写,而是从事更高层次的开发构架工作。他必须对开发技术非常了解,并且需要有良好的组织管理能力。可以这样说,一个架构师工作的好坏决定了整个软件开发项目的成败。在成为Java架构师之前,应当先成为Java工程师。熟练使用各种框架,并知道它们实现的原理。jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码;池技术,什么对象池,连接池,线程池……Java反射技术,写框架必备的技术,遇到有严重的性能问题,替代方案java字节码技术;nio,没什么好说的,值得注意的是"直接内存"的特点,使用场景;java多线程同步异步;java各种集合对象的实现原理,了解这些可以让你在解决问题时选择合适的数据结构,高效的解决问题,比如hashmap的实现原理,好多五年以上经验的人都弄不清楚,还有为什扩容时有性能问题?不弄清楚这些原理,就写不出高效的代码,还会认为自己做的很对;总之一句话,越基础的东西越重要,很多人认为自己会用它们写代码了,其实仅仅是知道如何调用api而已,离会用还差的远。如果你立志做架构,首先打好基础,从最底层开始。然后发展到各种技术和语言,什么都要懂两点,要全面且不肤浅。为什么不是懂一点?你要看得透彻,必须尽量深入一些。别人懂一点,你要做架构师,必须再多懂一点。比如你发现golang很流行,别人可能写一个helloworld就说自己玩过golang,但你至少要尝试写一个完整的应用。不肯下苦功,如何高人一头?另外你要非常深入地了解至少一门语言,如果你的目标是java,就学到极致,作为敲门砖,先吃饱了才能谈理想。3,架构师都是从码农过来的而Java学到极致势必涉及到设计模式,算法和数据结构,多线程,文件及网络IO,数据库及ORM,不一而足。这些概念放之一切语言都适用。先精一门,为全面且不肤浅打基础。另外就是向有经验的架构师学习,和小伙伴们讨论辩论争论。其实最重要的能力就是不断学习。在思考新的技术是否能更好地解决你们遇到的问题之前,你首先得知道并了解新的技术。架构师都是从码农过来的,媳妇熬成婆。千万不要成为不写代码的架构师,有些公司专门产不写技术的架构师。所谓架构师,只是功底深厚的程序员而已。个人认为应该扎扎实实学习基础知识,学习各种规范,架构,需要广泛的知识面,懂的东西越多视野越开阔,设计的东西当然会越好越全面。成为架构师需要时间的积累的,不但要知其然还要知其所以然。平时的一点一滴你感觉不到特别用处,但某天你会发现所有东西都没有白学的。4,架构师知识体系下面是我总结多年经验开发的架构师知识体系一、分布式架构架构分布式的英文( Distributed computing 分布式计算技术)的应用和工具,成熟目前的技术包括 J2EE,CORBA 和 .NET(DCOM),这些技术牵扯的内容非常广,相关的书籍也非常多。本文不介绍这些技术的内容,也没有涉及这些技术的细节,只是从各种分布式系统平台产生的背景和在软件开发中应用的情况来探讨它们的主要异同。分布式系统是一个古老而宽泛的话题,而近几年因为“大数据”概念的兴起,又焕发出了新的青春与活力。除此之外,分布式系统也是一门理论模型与工程技法。并重的学科内容相比于机器学习这样的研究方向,学习分布式系统的同学往往会感觉:“入门容易,深入难”的确,学习分布式系统几乎不需要太多数学知识。分布式系统是一个复杂且宽泛的研究领域,学习一两门在线课程,看一两本书可能都是不能完全覆盖其所有内容的。总的来说,分布式系统要做的任务就是把多台机器有机的组合,连接起来,让其协同完成一件任务,可以是计算任务,也可以是存储任务。如果一定要给近些年的分布式系统研究做一个分类的话,我个人认为大概可以包括三大部分:分布式存储系统分布式计算系统分布式管理系统二、微服务当前微服务很热,大家都号称在使用微服务架构,但究竟什么是微服务架构?微服务架构是不是发展趋势?对于这些问题,我们都缺乏清楚的认识。为解决单体架构下的各种问题,微服务架构应运而生。与其构建一个臃肿庞大,难以驯服的怪兽,还不如及早将服务拆分。微服务的核心思想便是服务拆分与解耦,降低复杂性。微服务强调将功能合理拆解,尽可能保证每个服务的功能单一,按照单一责任原则(Single Responsibility Principle)明确角色。将各个服务做轻,从而做到灵活,可复用,亦可根据各个服务自身资源需求,单独布署,单独作横向扩展。微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务的类上应用很多 SOLID 原则。微服务架构是个很有趣的概念,它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。概念:把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。定义:围绕业务领域组件来创建应用,这些应用可独立地进行开发,管理和迭代在分散的组件中使用云架构和平台式部署,管理和服务功能,使产品交付变得更加简单。本质:用一些功能比较明确,业务比较精练的服务去解决更大,更实际的问题。三、源码分析从字面意义上来讲,源文件的英文指一个文件,指源代码的集合。源代码则是一组具有特定意义的可以实现特定功能的字符(程序开发代码)。源码分析是一种临界知识,掌握了这种临界知识,能不变应万变,源码分析对于很多人来说很枯燥,生涩难懂。源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心。我认为是阅读源码的最核心驱动力我见到绝大多数程序员,对学习的态度,基本上就是这几个层次(很偏激哦):1,只关注项目本身,不懂就百度一下。2,除了做好项目,还会阅读和项目有关的技术书籍,看维基百科。3,除了阅读和项目相关的书外,还会阅读IT行业的书,比如学的Java的时,还会去了解函数语言,如LISP。4,找一些开源项目看看,大量试用第三方框架,还会写写演示。5,阅读基础框架,J2EE 规范,调试服务器内核。大多数程序都是第1种,到第5种不光需要浓厚的兴趣,还需要勇气:?我能读懂吗其实,你能够读懂的耐心,真的很重要。因为你极少看到阅读源码的指导性文章或书籍,也没有人要求或建议你读。你读的过程中经常会卡住,而一卡主可能就陷进了迷宫这时,你需要做的,可能是暂时中断一下,再从外围看看它:如API结构,框架的设计图。四、工具使用工欲善其事必先利其器,工具对 Java 的的程序员的重要性不言而喻现在有很多库,实用工具和程序任的 Java 的开发人员选择。下图列出的工具都是程序员必不可少的工具五、性能优化不管是应付前端面试还是改进产品体验,性能优化都是躲不开的话题。优化的目的是让用户有“快”的感受,那如何让用户感受到快呢?加载速度真的很快,用户打开输入网址按下回车立即看到了页面加载速度并没有变快,但用户感觉你的网站很快性能优化取决于多个因素,包括垃圾收集,虚拟机和底层操作系统(OS)设置。有多个工具可供开发人员进行分析和优化时使用,你可以通过阅读爪哇工具的源代码优化和分析来学习和使用它们。必须要明白的是,没有两个应用程序可以使用相同的优化方式,也没有完美的优化的 Java 应用程序的参考路径。使用最佳实践并且坚持采用适当的方式处理性能优化。想要达到真正最高的性能优化,你作为一个 Java 的开发人员,需要对 Java 的虚拟机(JVM)和底层操作系统有正确的理解。性能优化,简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短。性能问题永远是永恒的主题之一,而优化则更需要技巧。Java程序员如何学习才能快速入门并精通呢?当真正开始学习的时候难免不知道从哪入手,导致效率低下影响继续学习的信心。但最重要的是不知道哪些技术需要重点掌握,学习时频繁踩坑,最终浪费大量时间,所以有一套实用的视频课程用来跟着学习是非常有必要的。为了让学习变得轻松、高效,今天给大家免费分享一套阿里架构师传授的一套教学资源。帮助大家在成为架构师的道路上披荆斩棘。这套视频课程详细讲解了(Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构)等这些成为架构师必备的内容!而且还把框架需要用到的各种程序进行了打包,根据基础视频可以让你轻松搭建分布式框架环境,像在企业生产环境一样进行学习和实践。

auto_answer 2019-12-02 01:51:27 0 浏览量 回答数 0

回答

有编程能力和数据挖掘能力的工程师最火,包括:数据挖掘工程师、机器学习工程师,算法工程师。 今年3月份时,谷歌开发的人工智能AlphaGo打败了全球最顶尖的围棋高手,轰动全世界,AI时代正式拉开序幕。实际上,人工智能这一概念早在上世纪一大批科幻小说陆续发表时,就已被人们接受,而随着科技的发展,人工智能的发展前景更是日益清晰。一个人工智能的诞生需要无数个工程师挥洒汗水。其中,负责开发学习算法、使机器能像人类一样思考问题的数据挖掘工程师更是无比重要。什么人能完成人工智能的开发任务呢。必须指出,人工智能和一般的计算机程序有极大的差别,它应当具有“能够自主学习知识”这一特点,这一特点也被称为“机器学习”。而自学习模型(或者说机器学习能力开发)正是数据挖掘工程师的强项,人工智能的诞生和普及需要一大批数据挖掘工程师。  那么在AI时代,如何才能掌握相关的技能,成为企业需要的数据挖掘人才呢。 第一个门槛是数学 首先,机器学习的第一个门槛是数学知识。机器学习算法需要的数学知识集中在微积分、线性代数和概率与统计当中,具有本科理工科专业的同学对这些知识应该不陌生,如果你已经还给了老师,我还是建议你通过自学或大数据学习社区补充相关知识。所幸的是如果只是想合理应用机器学习算法,而不是做相关方向高精尖的研究,需要的数学知识啃一啃教科书还是基本能理解下来的。 第二个门槛是编程 跨过了第一步,就是如何动手解决问题。所谓工欲善其事必先利其器,如果没有工具,那么所有的材料和框架、逻辑、思路都给你,也寸步难行。因此我们还是得需要合适的编程语言、工具和环境帮助自己在数据集上应用机器学习算法。对于有计算机编程基础的初学者而言,Python是很好的入门语言,很容易上手,同时又活跃的社区支持,丰富的工具包帮助我们完成想法。没有编程基础的同学掌握R或者平台自带的一些脚本语言也是不错的选择。 Make your hands dirty 接下来就是了解机器学习的工作流程和掌握常见的算法。一般机器学习步骤包括: 数据建模:将业务问题抽象为数学问题; 数据获取:获取有代表性的数据,如果数据量太大,需要考虑分布式存储和管理; 特征工程:包括特征预处理与特征选择两个核心步骤,前者主要是做数据清洗,好的数据清洗过程可以使算法的效果和性能得到显著提高,这一步体力活多一些,也比较耗时,但也是非常关键的一个步骤。特征选择对业务理解有一定要求,好的特征工程会降低对算法和数据量的依赖。 模型调优:所谓的训练数据都是在这个环节处理的,简单的说就是通过迭代分析和参数优化使上述所建立的特征工程是最优的。 这些工作流程主要是工程实践上总结出的一些经验。并不是每个项目都包含完整的一个流程,只有大家自己多实践,多积累项目经验,才会有自己更深刻的认识。 翻过了数学和编程两座大山,就是如何实践的问题,其中一个捷径就是积极参加国内外各种数据挖掘竞赛。国外的Kaggle和国内的阿里天池比赛都是很好的平台,你可以在上面获取真实的数据和队友们一起学习和进行竞赛,尝试使用已经学过的所有知识来完成这个比赛本身也是一件很有乐趣的事情。 另外就是企业实习,可以先从简单的统计分析和数据清洗开始做起,积累自己对数据的感觉,同时了解企业的业务需求和生产环境。我们通常讲从事数据科学的要”Make your hands dirty”,就是说要通过多接触数据加深对数据和业务的理解,好厨子都是食材方面的专家,你不和你的“料”打交道,怎么能谈的上去应用好它。 摆脱学习的误区 初学机器学习可能有一个误区,就是一上来就陷入到对各种高大上算法的追逐当中。动不动就讨论我能不能用深度学习去解决这个问题啊。实际上脱离业务和数据的算法讨论是毫无意义的。上文中已经提到,好的特征工程会大大降低对算法和数据量的依赖,与其研究算法,不如先厘清业务问题。任何一个问题都可以用最传统的的算法,先完整的走完机器学习的整个工作流程,不断尝试各种算法深挖这些数据的价值,在运用过程中把数据、特征和算法搞透。真正积累出项目经验才是最快、最靠谱的学习路径。 自学还是培训 很多人在自学还是参加培训上比较纠结。我是这么理解的,上述过程中数学知识需要在本科及研究生阶段完成,离开学校的话基本上要靠自学才能补充这方面的知识,所以建议那些还在学校里读书并且有志于从事数据挖掘工作的同学在学校把数学基础打好,书到用时方恨少,希望大家珍惜在学校的学习时间。 除了数学以外,很多知识的确可以通过网络搜索的方式自学,但前提是你是否拥有超强的自主学习能力,通常拥有这种能力的多半是学霸,他们能够跟据自己的情况,找到最合适的学习资料和最快学习成长路径。如果你不属于这一类人,那么参加职业培训也许是个不错的选择,在老师的带领下可以走少很多弯路。另外任何学习不可能没有困难,也就是学习道路上的各种沟沟坎坎,通过老师的答疑解惑,可以让你轻松迈过这些障碍,尽快实现你的“小”目标。 机器学习这个领域想速成是不太可能的,但是就入门来说,如果能有人指点一二还是可以在短期内把这些经典算法都过一遍,这番学习可以对机器学习的整体有个基本的理解,从而尽快进入到这个领域。师傅领进门,修行靠个人,接下来就是如何钻进去了,好在现在很多开源库给我们提供了实现的方法,我们只需要构造基本的算法框架就可以了,大家在学习过程中应当尽可能广的学习机器学习的经典算法。 学习资料 至于机器学习的资料网上很多,大家可以找一下,我个人推荐李航老师的《统计机器学习》和周志华老师的《机器学习》这两门书,前者理论性较强,适合数学专业的同学,后者读起来相对轻松一些,适合大多数理工科专业的同学。

管理贝贝 2019-12-02 01:21:46 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站