编程思想培养当然要多练习总结了,我就以编程思想中算法 —— 逻辑思维来举例子吧。
在具体解决问题的过程中,最关键的能力有两个 ——“逻辑思维”和“调试纠错”。
程序员圈子很流行的一个笑话。
娃妈给程序员老爸打电话:“下班顺路买10个包子带回来,如果看到卖西瓜的,就买一个。”
结果娃爸手捧一个包子进了门。娃妈怒道:“你怎么就只买了一个包子?!”
娃爸答曰:“因为看到了卖西瓜的。”
虽然是一个黑程序猿的笑话,但也体现了很典型的编程思维。编程就是理性严谨地与电脑对话,因此对编程者的逻辑思维能力也有很高的要求。
逻辑思维中有个很重要的原则叫 MECE(Mutually Exclusive and Collectively Exhaustive),意思就是“相互排斥且整体完备”,也就是“不重复,不遗漏”。
在编程的算法中,需要处处考虑MECE原则。解数学题时,也是同一个道理——我们要保证答案中考虑到所有的情况,而这些情况既不遗漏,也不重叠。
调试纠错能力
编程的世界里,只有对与错,没有模糊值。在程序运行的过程中,只要最终的结果与期望不符合,就证明算法中肯定有错漏。
但是,程序中的bug常常不是一下就能找到的,需要我们把程序的运行顺序一步步地跟走一遍,同时观察每一步的运行结果。这就需要很多的耐心、观察力和专注力,对抗挫能力也是一种磨练。在这个过程中,也会逐渐懂得一个道理:犯错很正常,纠正它,下次不再犯类似的错误就好。
这一点,也是优秀的人身上常常共通的一项品质。这些人总是在进步,因为他们懂得“回溯、调试、纠错”,不断进行自我优化和成长,不断be better。
希望对你有所启发帮助
㈡ 怎么学程序员编程
学程序员编程可参考如下:
对于初学者来说,可以采用视频+书籍的方式进行学习。这两种方式形成互补关系。编程教学视频可以让人迅速掌握编程,但通常比较生动、浅显,不成系统。
编程书本是比较系统、深入的,但是枯燥,所以最好的方法是书和视频结合。当人已经过了入门期之后,看书、看视频、看博客就可以随心所欲。
其实软件工程发展到今天,编程已经是一个很“职业化”的技能。业内自嘲“IT民工”,每天“搬砖”之类的,就是这种现象的反应。不扯远了,总之一句话,基本上都是些是个人都能学会的技术,没有什么神秘的。
某些培训机构招一些高考失利的考生,培训两年就把他们往公司里送,他们也一样能胜任工作。所以自学也不是件难事。但前提是,你走对了路。
如果你从二进制、编译原理、数据结构……这些开始,我估计你陷在里面就出不来了——除非有名师指点或者天赋异禀,再或者有大机缘?
不要急着做这些“学究”式的学习研究,就像学开车一样,不需要你从发动机原理学起是一样的。程序/语言是让你用的,就像车是让你开的,明白了这一点,你就可以立马轻松100倍。
所以,先选一辆“好开“的车,迅速的跑起来,享受这种微风拂面的快感和刺激,才是最重要的。
㈢ 好的程序员应该掌握的几门编程语言
应该掌握至少一门强类型,静态语言。 即java,C#,C++中的一种,或以上。
静态语言和动态语言,就像汽车和自行车。如果去市场买菜,一定是自行车方便,但如果出趟远门,你才会明白汽车好在哪里。必须掌握一门静态语言,你才能具备编写大型程序的能力。掌握静态语言的程序员,和只懂脚本语言的程序员,是两个完全不同的概念。只有会开汽车,才是真正的司机。
至少要掌握JAVASCRIPT或TYPESCRIPT。即便你不做网站,你也很难避免和web相关的代码打交道。因为今天的APP,有很大一部分,是用网站封装而成的。因此JAVASCRIPT虽然有很多缺点,但它却非常重要。由于JAVASCRIPT是脚本语言,并不利于编写大型逻辑,因此TYPESCRIPT也是个很好的选择。当然如果你对自己的JS水平很有自信,可以坦然面对“回调地狱”(JS程序必须克服的巨大挑战,所有中型以上的程序都会遇到),那只用JS也可以。否则的话,你可以考虑用TYPESCRIPT,这玩意比ECMA组织的那些解决方案靠谱太多了,现在市面上的H5的游戏,绝大部分都是用TYPESCRIPT编写的。
㈣ 想学习制作简单的jar格式的手机游戏,请问有什么好的开发软件还有,有什么JAVA语言编译器
java编译器是c语言写的,开发软件只是集成了c语言的java编译器和友好的界面,作为平台让程序员更舒服地编程。java写完程序同样是程序文件,不是安装文件,导出为jar则是jar包里面包含scr、bin和res文件夹,有相应的.java,.class和图像文件。手机有java编译功能则将jar包里的文件编译即为安装过程,进入游戏则是运行过程,文件已经在安装时编译过。
用Eclipse作为开发软件,集成sun的midp功能,以前是wireless toolkit for cldc,现在更新换代了。Eclipse是比较好的选择,无论J2ME还是Android。只有安装正确的插件,便可进行java手机开发。有了类似wireless toolkit的插件,在写完程序编译完成后便可直接选择将程序以jad包形式调试,导出成jar包,在deployed文件夹里便可看到jad和jar文件,jar便是可以安装到手机里的那个安装文件。
答得有点莫名其妙还望谅解,我很久以前用的J2ME,答楼主的问题就回顾了一下。
一开始学习java肯定不能从J2ME开始了吧,从简单的功能和例子开始,高级程序语言的概念殊途同归,如果概念清楚,只要把包里的api记住就能写了。从J2SE的application和applet开始。
㈤ C文件如何成为可执行文件(编译、链接、执行)——摘自《程序员的自我修养》
本文算是我阅读《程序员的自我修养》(俞甲子等着)相关章节的笔记,文中直接引用了原书中的叙述,强烈建议大家去看原书,本文只做概要介绍而用。——注:文中有很多引用图的地方,请大家自己去找原书看,支持正版!我遇到一个问题,Linux C编程中的问题:.. char *p; unsigned int i = 0xcccccccc; unsigned int j; p = (char *) &i; printf("%.2x %.2x %.2x %.2x\n", *p, p[1], p[2], p[3]); memcpy(&j, p, sizeof(unsigned int)); printf("%x\n", j); ... Output: ffffffcc ffffffcc ffffffcc ffffffcc 0xcccccccc My questions are: 1. Why it prints "ffffffcc ffffffcc ffffffcc ffffffcc"? (if p is unsigned char* then it will print correctly "cc cc cc cc") 2. Why pointer to char p copied to j correctly, why not every member in p overflow? since it is a signed char. 这是别人在邮件列表中提出的问题,在试图回答这个问题的过程中,突然发现,自己对连接器的工作并不熟悉,因此拿来好书《程序员的自我修养》来看,并做如下汇报,强烈推荐《程序员的自我修养》!!!写好的C语言文件,最终能够执行,大致要经过预处理、编译、汇编、链接、装载五个过程。预编译完成的工作: (1)将所有的"#define"删除,并展开所有的宏定义 (2)处理所有条件预编译指令 (3)处理#include预编译指令,将被包含的文件插入到预编译指令的位置,这个过程是递归进行的。 (4)删除所有的注释 (5)添加行号和文件名标识,以便调试 (6)保留所有的#pragma编译器命令,因为编译器需要使用它们。编译完成的工作: (1)词法分析 扫描源代码序列,并将其分割为一系列的记号(Token)。 (2)语法分析 用语法分析器生成语法树,确定运算符号的优先级和含义、报告语法错误。 (3)语义分析 静态语义分析包括生命和类型的匹配,类型的转换;动态语义分析一般是在运行期出现的与语义相关性的问题,如除0错。 (4)源代码生成 源代码级优化器在源代码级别进行优化:如将如(6+2)之类的表达式,直接优化为(8)等等。将语法书转换为中间代码,如三地址码、P-代码等。 (5)代码生成 将源代码转换为目标代码,依赖于目标机器。 (6)目标代码优化汇编完成的工作: 将汇编代码变成机器可以执行的指令链接完成的工作: 链接完成的工作主要是将各个模块之间相互引用的部分处理好,使得各个模块之间正确衔接。链接过程包括:地址和空间分配、符号决议和重定位。 首先讲静态链接,基本的静态链接如下: 我们可能在main函数中调用到定义在另一个文件中的函数foo(),但是由于每个模块式单独编译的,因此main并不知道foo的地址,所以它暂时把这些调用foo的指令的目标地址搁置,等到最后链接的时候让连接器去修正这些地址(重定位),这就是静态链接最基本的过程和作用;对于定义在其他文件中的变量,也存在相同的问题。具体过程如下: (1)空间和地址分配 1)空间与地址分配:扫描所有输入目标文件,获得各个段的属性、长度和位置,并且将目标文件中的符号表中所有的符号定义和符号引用收集起来,放到一个全局符号表中。 2)符号解析和重定位:使用第一步收集到的信息,读取输入文件中段的数据、重定位信息,并进行符号解析与重定位、调整代码中的地址等。 动态链接的过程更为复杂,但是完成的工作类似。 动态链接的初衷是为了解决空间浪费和更新困难的问题,把链接过程推迟到运行时进行 首先介绍一个重要的概念——地址无关代码。为了解决固定装载地址冲突的问题,我们希望对所有绝对地址的引用不作重定位,而把这一步推迟到装载的时候再完成,一旦模块装载地址确定,即目标地址确定,那么系统对程序中所有的绝对地址引用进行重定位。同时我们希望,模块中共享的指令部分在装载时不需要因为装载地址的改变而改变,所以把指令中那些需要被修改的部分分离出来,跟数据放在一起,这样指令部分就可以保持不变,而数据部分可以在每个进程中拥有一个副本,这种方案目前被称为地址无关代码(PIC,Position-independent Code)。 我们需要解决如下四种引用中的重定位问题: 1)模块内部调用或者跳转:这个可以用相对地址调用或者基于寄存器的相对调用,所以不需要重定位2)模块内部数据的访问:用相对寻址的方法,不过链接器实现得十分巧妙: call494 <__i686.get_pc_thunk.cx> add$0x188c, %ecx mov$0x1, 0x28(%ecx) //a=1 调用一个叫做__i686.get_pc_thunk.cx的函数,把call的下一条指令的地址放到ecx寄存器中,接着执行一条mov指令和一个add指令3)模块间数据的访问:在数据段里建立一个指向全局变量的指针数组,也成全局便宜表(GOT),当要引用全局变量时,可以通过GOT相对应的项间接引用: GOT是做到指令无关的重要的一环:在编译时可以确定GOT相对于当前指令的偏移,根据变量地址在GOT中的偏移就可以得到变量的地址,当然GOT中哪个每个地址对应于哪个变量是由编译器决定的。4)模块间的调用、跳转:采用上面类似的方法,不同的是GOT中相应的项存储的是目标函数的地址,当模块需要调用目标函数时,可以通过GOT中的项进行间接跳转。 地址无关代码小结: 现在,来看动态链接中的另一个重要问题——延迟绑定(PLT)。当函数第一次被用到时才进行绑定,否则不绑定。PLT为了实现延迟绑定,增加了一层间接跳转。调用函数并不是通过GOT跳转的,而是通过一个叫PLT项的结构进行跳转的,每个外部函数在PLT中都有对应的项,如函数bar,其在PLT对应的项的地址记为bar@plt,实现方式如下: bar@plt: jmp* (bar@GOT) pushn pushmoleID jump_dl_runtime_resolve 链接器的这个实现至为巧妙: 如果在连接器初始化阶段,已经正确的初始化了bar@GOT,那么这个跳转指令的结果正是我们所期望的,但是,为了实现PLT,一般在连接器初始化时,将"pushn"的地址放入到bar@GOT中,这样就直接跳转到第二条指令,相当于没有进行任何操作。第二条指令“pushn”,n是bar这个符号引用在重定位表“.rel.plt”中的下标。接着将模块的ID压栈,跳转到_dl_runtime_resolve完成符号解析和重定位工作,然后将bar的地址填入到bar@GOT中。下次再调用到bar时,则bar@GOT中存储的是一个正确的地址,这样就完成了整个过程。 在链接完成之后,就生成了你要的可执行文件了,如ELF文件,至于这个文件的详细的信息,可以参考相关的文档。 现在,你要运行你的可执行文件,这是如何做到的呢? 我们从操作系统的角度来看可执行文件的装载过程。操作系统主要做如下三件事情:(1)创建一个独立的虚拟地址空间,但由于采用了COW机制,这里只是复制了父进程的页目录和页表,甚至不设置映射关系(参考操作系统相关书籍)。(2)读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系。(3)将CPU的指令寄存器设置成可执行文件的入口地址,启动运行。我们来看一下执行过程中,进程虚拟空间的分布。 首先我们来区分Section和Segment,都可以翻译为“段”,那么有什么不同呢?从链接的角度来讲,elf文件是按照Section存储的,从装载的角度讲,elf文件是按照Segment存储的。”Segment”实际上是从装载的角度重新划分了ELF的各个段,将其中属性相似的Section合并为一个Segment,而系统是按照Segment来映射可执行文件的。
㈥ 作为一个好的程序员,都需要具备哪些基本的
你好,小U来为您解答这个问题,众所周知,程序员是从事程序开发、维护的专业人员。
作一个真正合格的程序员,需要具备:
1:团队精神和协作能力
团队精神和协作能力是作为一个程序员应具备的最基本的素质。
2:文档习惯
文档是一个软件系统的生命力。作为代码程序员,必须将30%的工作时间写用于技术文档。没有文档的程序员势必会被淘汰。
3:规范化的代码编写习惯
知名软件公司的代码的变量命名、注释格式,甚至嵌套中行缩进的长度和函数间的空行数字都有明确规定,良好的编写习惯,不但有助于代码的移植和纠错,也有助于不同技术人员之间的协作。
4:需求理解能力
程序员要能正确理解任务单中描述的需求。
5:模块化思维能力
作为一个优秀的程序员,其思想不能在局限当前的工作任务里面,要想想看自己写的模块是否可以脱离当前系统存在,通过简单的封装在其他系统中或其他模块中直接使用。
6:测试习惯
测试是软件工程质量保证的重要环节,但是测试不仅仅是测试工程师的工作,而是每个程序员的一种基本职责。程序员要认识测试不仅是正常的程序调试,而要是要进行有目的有针对性的异常调用测试,这一点要结合需求理解能力。
7:学习和总结的能力
程序员是很容易被淘汰的职业,所以要善于学习总结。