对于许多编程开发程序员来说,组织开发架构等技术应该都掌握了不少了,那么大家是否懂得算法相关的技术呢?今天,昆明电脑培训http://www.kmbdqn.com/就一起来了解一下,程序员为什么要学习算法以及应用领域的问题。
学习算法的重要性
在介绍具体算法之前,我先谈一下个人对学习算法的初心。我的初心无非有两点:一,BAT等互联网公司招聘面试时要问算法知识,如果想要进入互联网公司,我就必须学好算法二,通过学习算法提升个人开发的基本功,这样一来,对于不同场景我就可以正确选择对应的数据结构和算法,使得程序更健壮,提高程序的运行效率。
应用领域
目前计算机各个细分领域涉及到不同的算法。比如说搜索引擎,平时我们使用google、百度等浏览器,只要我们输入一个关键字,浏览器就会快速地返回相关的集合,这个集合的背后就隐藏着许多算法。如果没有这些算法,我们是不可能这么快速地得到想要的结果。再比如说人工智能,通过计算模型算法实现人体识别、语音识别等各应用场景。
算法分析
上文我们已经介绍到算法就是解决问题的方法,而对于同一个问题,可能存在不同的解决方法。因此,为了衡量一个算法的优劣,提出了时间复杂度与空间复杂度这两个概念。
时间复杂度
一般情况下,算法中基本 *** 作重复执行的次数是问题规模n的某个函数f(n),算法的时间度量记为T(n)=O(f(n)),它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称时间复杂度。
空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量。
应用太多了。
基本上来说C#是基于面向对象语言,你所定义的所有类/结构体都算是数据结构,而且在.net类库中已经定义中诸多可用的类型以供使用。实际开发中根本就离不开结构与算法。
题主之所以有这样的问题,基本上认识到了很多程序员易犯的一个毛病——理论知识与实际应用中的脱节问题,不少程序员都说自己写程序用不上理论知识,或者是理论无用。我一直认为理论才是真正编程的指导,别说你所学的理论知识了,有时我们必须遵守一些软件活动上的标准/规范/规定。比如ISO29500标准有多少程序员读过或听说过?他实事就是关于openxml的一个国际标准,我们要想达到通用的程序,这些标准还是读一读的好。
扯回你的问题,什么是数据结构,什么是算法?如果你真的狭义理由数据结构,或者只是从课本上例子来说,数据结构被定义成一个只有属性成员的类或结构体才算是数据结构吗?事实上并不是,那么是不是只有链表/栈/队列才算是数据结构呢?可以说这是某些人狭义理解数据结构时的一种常规定势思维,但事实上来说,类或结构是数据结构的基本,否则你链表存在的实体到底是什么东西?所以数据结构包含着基本结构与狭义上的顺序表/链表/栈/队等存在实体的集体。为什么我说数据结构在实际运用中广泛体现呢?就数据结构而言,课本上只是为了讲明白结构而已,弱化了其中实体的真正含义,而且不语言的具体实现亦不尽相同,所以他们所讲的数据结构是基本理论的。
我来个例子:链表(C#语言)
public class Member{
public string Name{getset}
public string Responsibility{getset}
public string Posotion{getset}
}
public class MemberNode
{
public Member Member{getset}
public Member Next{getset}
}
// Node其他就是链表中的一个结点结构,这个结点结构除了指明当前的Member之下还指向下Next的下一个结构结构,它最终可以形成一个链表。这就是定义的一个链表。
从以上例子上你可以看出这是一个类似于课本的标准定义,但事实上在C#语法中存在泛型的特点,那么这类似的结构我们不须要一个个地定义了!所以在不同的语言中为了方便编程者,我们甚至可以把这样的结构进行简单化,从而达到一种最简单的使用方式。以C#为例,我们可以使用Node<T>来表示链表/List<T>表示顺序表/Stack<T>表示栈/Queue<T>表示队列,在这种情况下,我们只需要定义我们的泛型即可,结构链之类的本身使用泛型已经在类库中实现了——虽然你不用定义,但不代表不使用或者不用理解这其中的知识。而在课本讲理论的时候,他不可能附带泛型来讲的,所以很多人认为自己去定义数据结构才行,那才是“真正”的数据结构,其实不然。以链表为例,我们需要一个节点除了其实体意义之外,还存在指向下一结点的指针(其实是地址引用)才算是数据结构。根据课本,他们必须这么定义(C#):
public class MemberNode{
public string Name{getset}
public string Responsibility{getset}
public string Position{getset}
public MemberNode Next{getset}
}
// 死读书的只会承认这种才是真正的数据结构吧(链表节点)
事实上,链表讲的只是一种形式,能最终形成的一种组织数据结构的形式。这个代码会导致我们出现一种极大的误解——每个类型的结构都需要重新定义一次。如果有多个类型结构的话,我们会出现多个不同的定义,这会导致将来类的定义越来越多,对于维护上来说是比较麻烦的。由于设计模式/面向切片等各种开发方式的介入,我们会使用相对比较简单的形式。所以才会有我定义两个类的进步,而后可以出现泛型的更进一步。
你可以这样理解,这种课本上的结构,会导致我们造成每种结构基本上都需要重新定义一次,我最开始给出的例子可以使用继承的方式,实现某个基类的数据结构(下面的似乎也行,但在使用中可能会出现部分问题),而Node<T>则从根本上解决了这个问题,可以支撑多种类型。
所以此时在理解数据结构时,比如Node<T>,他不旦要求理解链表的节点,还要理解T泛型,那么在数据结构上来说,它指的不再是单一的节点结构,还在包括一个基础的类型。
换句话来说,你在C#等语言中已经不需要再做类似的定义了,只需要定义其基本结构类型即可。但课本上在讲知识的时候,它不可能只针对面向对象或支持泛型的语言来讲,若不支持泛型时,我们必须使用课本上或我最开始写的例子中的形式,若不支持继承的面向过程语言,那么课本上的知识就是硬性的规定,你必须以这种形式来说,而引用则使用指针引用的方式(面向对象的引用其实是一种引用型引用,也就是址引用或称地址引用,与指针类似)。
相信讲到这里你能明白,数据结构在不同的语言中只是变了个形而已,并不是必须是存在指针的才是,也不是只说表面上的那点东西。早期教程都是以fortain语言为主的,而且课本的目的是讲清道理,而不是一种规定。死读书的人以为用不到数据结构,其实他们一直在使用。
再来说一下算法,算法是什么?是解决问题的一种模式,比如解二元一次方程等等,所以算法的定义其实已经告诉你,顺序代码他也算是一种算法,不能说只有背包问题,八皇后问题,回溯问题才算是算法——你能明白吗?其实你正常写的就是一种算法,这种算法简单,就是顺序执行下来就可以了,他也是一种算法的,就算解二元一次方程组有固定的模式(算法),但不代表加减法就不是算法了!所以算法也是常用的东西,那么你学习的算法其实算是开辟思路的一种而已。算法自身的概念已经决定,基本上程序都是由结构与算法构成。我也来举个例子,怎么判断某个链表是否为循环链表?是你的回溯算法,贪心算法还是背包算法?它们只是在解决一些典型问题的一种通用方式而已,很显然,我的问题不是这种典型问题,但不代表他不典型,我们正常的算法是设计两个变量等于头元素,然后开始进入循环,一个变量每次向下推一,即找到他下一个节点,而另一个变量每次找到其孙节点,就算当于两个变量一个每次向下推进一次,而另一个每点推进两次(如果可能),如果不是循环链表,则进两次的那个会在链表总长度的一半时,遇到空引用,否则会在某一时间两指针引用同一对象(不是对象相等,而是引用相同的对象),什么意思呢,好象两个人在圆型跑道上跑步,一个每秒1米,另一个每秒2米,同时同地同向出发,最归跑得快的那个会追上跑得慢的那个!当然这种情况下你也可以给他起个名字,叫“追及算法”?如果只有你学的那几个典型算法是算法的话,这个算不算算法?
现在我们的问题是,如果语言层面上已经实现了这些东西,那么这些理论我们是否可以不用理解就可以了?答案是可以——如果你只是一个不思进取的程序员或允许bug乱飞的没有责任心的编程人员的话,可以不用理解——毕竟有些人只是“混”饭吃而已!
理解了不会去应用,这就是典型的理论联系不到实际,他们也不知道自己的代码将如何控制。我举一个例子,由于性能等各方面的要求,我们要使用多线程对某些数据进行处理。怎么处理?不好人会使用多线程——他们定义一个临界资源,然后让多个线程在读取数据表(DataSet)时进行阻塞,然后每个线程去处理那些超时长的问题,处理完的时个再按这种方式读取数据——这样有问题吗?没有,这也算是算法的一种!反正如果编程代码有功底的话没有任何问题的,这种代码算不算优雅呢——很多人认为代码的优雅就是代码编写过程的形式或是良好的编程习惯!这里边其实用不到数据结构与算法的。
好吧,我承认,但如果我们换一句思路来看看,如果我用一个线程负责读取数据,并不停地放入到一个队列中,而多个线程从队列中不停地读取处理这些放入的数据,这样如何?我的意思是说,并没有直接在DataSet中处理,而是选择使用队列的方式。
我们看一个问题,这个队列Queue<T>,一个线程用来插入数据,多个线程用来读取数据,而且要保证不能重复,那么我们可以使用队列的安全版本(CorrentQueue<T>,在.net中如果非线程安全的情况下,多线程使用实应该找到其对应的安全版本或者控制线程安全)。
插入线程如果发现队列中的长度(容量)较大时,可以暂缓插入。这样可以保证队列的长度基本固定,占用内存得到控制(不是DataSet批量读来一大堆),由于使用安全队列,所以各线程不用考虑线程之间的安全问题,每个线程从队中获得数据并删除,可以保证数据只被处理一次。当然还可以考虑优雅的通知机制,插入线程在插入数据时通知处理线程启动,如果插入速度过快,发现插入数量达指定的长度(比如30个),停止插入,插入线程阻塞;处理处理再次处理时可通知插入线程再进行插入。
这也算是一种算法吧?它可以让插入线程与处理线程同时工作,而使用DataSet那种常规的结果时,只能是等待处理完或加入多个控制条件进行控制,既然这么控制的话,何不直接使用队列的方式?CorrentQueue<T>中的T也完全可以是一条记录DataRow嘛!
如果你认为第一种是你经常使用方式,那么算法对于你来说学与不学无所谓的,你必须使用自己的编程/调试功底以保证你的代码尽量很少出错或不出错。而如果你认为第二种方案优雅一些的话,那么你会认为你学习的算法与结构还是有用的,理论与实践结合了。
我之所以举这么一个例子,其实告诉你的无非是几点非常重要的信息:
你有选择算法的自由(只不过是代码质量、后期维护的问题)
如果你知道的较多的算法与结构,你会有更多的选择。
算法或结构在实际使用中,所谓的典型问题并不是使用场景和书上描述一模一样(试想一下,我第二种考虑的例子中,是不是跟书上比他不典型?其实也是非常典型的)
分析问题时,应该拿要点,而不是整体去套。(如果整体去套用的话,你肯定会想不到使用哪种结构或算法)
不管是数据结构/算法/设计模式都要求是灵活运用,而不是场景对比使用,也不是生搬硬套。
试想一下,你的背包问题,怎么可能公司也让你分拆包装?你的八皇后问题公司恰好让你下棋?你的贪心算法公司恰好让你找零钱?你的回溯算法公司恰好让你走迷宫?学不能致用的原因就是太死板——这几个举个例子的场景你再遇到或理能遇到的机率是非常小的,所以如果觉得学了没用,那就真没用了——只不过不是算法没用,而是人没人!
讲个小故事:从前一个家人的板凳坏了,要找一个合适的两股叉的树杈重新制做一个板凳腿,让孩子到树园里找了半天,孩子回来说“我都没见过有向下叉的树杈!他老爹气得要死——怎么会可能有向下长的树杈呢!这孩子是不是笨——你就不会把地刨了找一个向下分叉的树根!
算法也是一样,迷宫找路可以使用回溯算法,但不是所有的回溯算法都用于迷宫找路——它还可以用来设计迷宫!嘿嘿嘿!
在填报高考志愿时,有小伙伴比较关心人工智能专业有哪些就业方向?下面是由编辑为大家整理的“人工智能专业主要学什么 就业方向有哪些”。
人工智能专业要学哪些课程数学基础课程:高等数学,线性代数,概率论数理统计和随机过程,离散数学,数值分析等。
算法基础课程:人工神经网络,支持向量机,遗传算法等,还有各个领域需要的算法,比如你要让机器人自己在位置环境导航和建图就需要研究SLAM。
人工智能是一个综合学科,人工智能专业的主要领域是:机器学习、人工智能导论、图像识别、生物演化论、自然语言处理、语义网、博弈论等。
人工智能专业的就业方向1、算法工程师。进行人工智能相关前沿算法的研究,包括机器学习、知识应用、智能决策等技术的应用。以机器学习的过程为例,涉及到数据收集、数据整理、算法设计、算法训练、算法验证、算法应用等步骤,所以算法是机器学习开发的重点。
2、程序开发工程师。一方面程序开发工程师需要完成算法实现,另一方面程序开发工程师需要完成项目的落地,需要完成各个功能模块的整合。
3、人工智能运维工程师。大数据与AI产品相关运营、运维产品研发相关组件的运维工具系统的开发与建设提供大数据与AI云产品客户支持。
4、智能机器人研发工程师。研发方向主要从事机器人控制系统开发,高精度器件的设计研发等。工业机器人系统集成方向主要做工作站设计,电气设计,器件选型,机器人调试,编程,维护等。
5、AI硬件专家。AI 领域内另外一种日益增长的蓝领工作是负责创建 AI 硬件(如 GPU 芯片)的工业 *** 作工作。大科技公司目前已经采取了措施,来建立自己的专业芯片。
人工智能专业的就业前景人工智能是一个快速发展的领域,现在及未来对人才的需求量很大。和其他技术岗位相比,人工智能的人才少,竞争低,工资相对高。所以现在是进入人工智能领域的好时机。人工智能是目前最受互联网界和市场关注的新技术。全球主要互联网企业均在向人工智能方向转型,并大幅增加相关科研、技术和产业应用布局方面的投入。
人工智能将大幅改善依赖劳动力创造的劳动密集型、简单重复性的传统经济运行模式,并依托此经济模式构建万物互联、智能协同的产业体系,打造国际领先的智能社会。人工智能将实现提升效率、降低成本的发展。
人工智能相关技术将首先在互联网行业开始应用,然后陆续普及到其他行业。所以,从大的发展前景来看,人工智能相关领域的发展前景还是非常广阔的。人工智能作为重要的技术之一,必然会在产业互联网发展的过程中释放出大量的就业岗位。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)