| 风声竹影 的个人资料听风竹轩的书架日志列表网络 | 帮助 |
|
3月20日 linux库文件的编写linux库文件的编写 作者: laomai 本文主要参考了如下资料 二、静态库与动态库 2、 编译测试程序,与静态库类似,要把头文件的路径加到-I参数里面 六、使动态库被系统共享的三种办法 七、动态库的显式调用 ⑶用dlerror()函数测试是否打开成功,并进行错误处理; 3、执行测试程序 六、使用动态库时应注意的其他问题 ⑵用动态库隐式连接时的结果 ⑶动态库显式连接时的结果 CNNIC称IPv4地址将耗尽影响严重新浪科技讯 3月19日下午消息,中国互联网络信息中心(CNNIC)主任毛伟今日表示,要重视IP地址耗尽的严重影响,目前整个社会对IPv4地址耗尽问题的迫切性和产生的后果估计严重不足,他建议实施国家计划来应对。 资源耗尽影响面广 根据CNNIC分析,按现有每年约2亿个的IP地址消耗及年约19%的消耗增速,全球剩余IP地址将于2012年前后耗尽。由于历史原因,目前 我国已获得IPv4地址数量仅占全球已分配IPv4地址数量的4.5%,由于国际上可分配IP地址越来越少,争夺越来越白热化,我国未来可能争取的 IPv4地址数量也非常有限。 2006年5月份,也曾有外国调研机构预计,全球国际互联网IP地址资源到2010年将全部耗尽。毛伟在今天指出,IP地址耗尽将在三个方面产生影响。首先,将制约我国互联网的普及,制约互联网新业务、新应用的开放及规模性部署。 其次,IP地址的匮乏可能迫使人们普遍使用私有地址或动态地址进行通信,地址转换设备易形成网络的单点故障点和性能瓶颈,造成国家网络基础设施 运行效率低下、稳定性差;另外,私有地址不是合法地址,不能出现在公共网络中,网民将不能充分使用一些诸如视频点播、网络电话等端对端的互联网服务。 第三,从信息安全来看,私有和动态IP地址容易造成安全问题,例如网络垃圾邮件,网络入侵/攻击(包括木马),网络诱骗,网站欺诈、恶意发布虚 假信息等网络信息安全问题大多都是钻了地址隐藏无法有效追查的空子,给社会造成了巨大的损失,也给净化网络环境带来了相当大的管理难度。 建议实施国家计划 对于全球目前所面临的IP地址资源困境,中科院信息办专家近日表示,IPv4地址耗尽恰恰会促进我国互联网尽快向下一代互联网过渡,使得我国有 机会在下一代互联网的发展中昂立潮头,一举改变落后跟随的地位,给我国带来了战略发展机遇,同时能解决多年来制约我国互联网发展的瓶颈环节、影响我国网络 信息安全和管理的问题。 据了解,目前欧美日本等国家都已经制定并着手实施向IPv6过渡的战略规划。最具代表性的是美国军方和政府的过渡计划。虽然目前美国并不短缺 IPv4地址,但仍然有很强的紧迫感和危机意识,因而在向IPv6过渡方面态度是很坚决和明确的,美国军方和政府都出台了相应政策来推进向IPv6的过 渡。 应对IPv4地址耗尽及顺利向下一代互联网过渡问题,是个庞大的系统工程,中科院信息办专家建议政府实施国家行动计划进行应对,拿出过渡路线图、时间表和解决方案,抓住机遇积极推进。 IPv6商业模式仍需探索 对于IPv6的商业模式,中关村下一代互联网产业联盟理事长刘东称已经专门成立课题组进行研究。据他透露,目前探索的道路和“应用”有关,“我们在思索,什么产品能够应用IPv6的特性,如大量地址,端对端,我们看到视频监控是个机会。” 据刘东介绍,传统的视频监控由于IPv4地址经常变动,在随时性、安全性方面存在问题,而这恰好是IPv6的机会。刘东透露目前已经和运营商在探索这方面的模式,如向连锁商店提供支持IPv4和IPv6的终端,通过服务收费。 他指出,公共领域的服务和互联网新技术融合,必然是IPv6的机会,因为将出现运营商,而这个运营商既不是传统网络服务商,也不是电信运营商,处于中间地位。“有点类似阿里巴巴或者支付宝,提供专业的服务,就像电子运营商+携程的组合模式。” 刘东坦言,目前对IPv6商业模式仍处于初步探索阶段。但伴随IPv6网络的逐渐部署,必然能够发现一些新的创新点,从而进一步发展。(全智 韩枝) 3月19日 Linux静态/动态链接库的创建和使用Linux静态/动态链接库的创建和使用 和Windows系统一样Linux也有静态/动态链接库,下面介绍创建和使用方法: 假设有下面几个文件: /***********************************
/************************************** int Strlen(char *pStr) ulLength = 0; return ulLength;
********************************************** #include<stdio.h> int StrNlen(char *pStr, unsigned long ulMaxLen) assert(NULL != pStr); if(ulMaxLen <= 0) ulLength = 0; return ulLength;
生成动态链接库: 对应的链接库已经生成,下面看一下如何使用对应的链接库。 /***************************************** int main(int argc, char* argv[]) printf("The string is : %s\n", str); return 0;
动态库的分为隐式调用和显式调用两种调用方法: 在这种调用方式中,需要维护动态链接库的配置文件/etc/ld.so.conf来让动态链接库为系统所使用,通常将动态链接库所在目录名追加到动 态链接库配置文件中。否则在执行相关的可执行文件的时候就会出现载入动态链接库失败的现象。在编译所引用的动态库时,可以在gcc采用 –l或-L选项或直接引用所需的动态链接库方式进行编译。在Linux里面,可以采用ldd命令来检查程序依赖共享库。 显式调用:
/***************************************** int main(int argc, char* argv[]) char str[] = {"hello world"}; void *pdlHandle; pdlHandle = dlopen("./libstr.so", RTLD_LAZY); //加载链接库/libstr.so //get function from lib pStrnlenFun = dlsym(pdlHandle, "StrNlen"); printf("The string is : %s\n", str);
3月17日 林彪军事家。1907年生于湖北黄冈。1923年6月加入中国社会主义青年团。1925年考入黄埔军校第四期,同年转入中国共产党。1926年10月毕业后国民革命军叶挺独立团任排长,参加了北伐战争。1927年8月参加南昌起义。起义军在广东潮汕地区失败后,随朱德、陈毅转战闽粤赣湘边界。1928年1月参加湘南起义。同年4月随部队上井冈山,先后任红军第四军二十八团营长、团长,参加了巩固和发展井冈山革命根据地的斗争。1929年1月随军挺进赣南、闽西,3月任红四4军第一纵队司令员。1930年6月任红四军军长。1932年3月任红一军团总指挥(后称军团长),率部参加了长沙、赣州、漳州、南雄水口、乐安宜黄等重要战役和中央苏区历次反"围剿",多次指挥所部担任主攻任务。1934年10月率红一军团开始长征,参加突破国民党军四道封锁线和强渡乌江等作战。1935年1月参加了遵义会议,会后指挥所部参加四渡赤水、巧渡金沙江、强渡大渡河、夺占泸定桥等作战。同年9月任陕甘支队副司令员兼第一纵队司令员,到达陕北后率部参加了直罗镇战役和东征战役。1936年6月任中国人民抗日红军大学(后改称抗日军政大学)校长,后兼政治委员。抗战爆发后任八路军第115师师长,率部挺进华北前线,同聂荣臻指挥了平型关战斗。1938年冬赴苏联就医。1942年2月回国。抗战胜利后,先后任东北人民自治军总司令、东北野战军司令员等职,与罗荣桓等指挥了四平、新开岭、三下江南四保临江和辽沈战役等重要战役,解放全东北。1948年底率部入关,与罗荣桓、聂荣臻一起指挥平津战役。1949年3月起任第四野战军司令员等职,先后指挥了湘赣、衡宝、广东、广西等战役。 3月16日 高善文:股市将进入下半场高善文,安信证券研究所首席经济学家,中国人民银行研究生部博士。先后任职于中国人民银行总行办公厅和国务院发展研究中心金融研究所,2003年进入光大证券研究所,2007年进入安信证券研究所。 中国宏观经济:进入繁荣 中国股市:下半场 2008年底A股(沪深300(4157.528,-41.43,-0.99%,吧))收盘点位:达到6700点 2008年底人民币兑美元汇率:6.54 考虑到2008年的整体环境,我们认为可能出台的主要政策包括加快汇率升值、继续调整利率、严格控制信贷。从经济运行来说,经济增速将逐步放缓、通货膨胀压力的下降还需要一些时间,而资本市场在资金面可能感受到间歇性的压力。 从中长期的经济周期意义上看,如果我们可以把一个经济周期分解为扩张期、繁荣期、收缩期和衰退期四个时期,那么自从2002年以来的本轮经济周期的扩张期在2007年上半年可能已经基本完成,并正在转入繁荣期,这样的繁荣期有可能持续几年的时间。 2008年中国全年贸易顺差的规模可能会维持在3000亿美元附近。看起来2008年人民币对美元的汇率升值幅度很可能会达到8%-10%的水平,相比2007年明显提速,这无疑会刺激资本流入规模的放大。我们认为,如果2008年外资流入规模达到2000亿美元,应该不会让人意外。 考虑到最近的次贷危机和联储降息对全球资本流动的影响,我们的结论是,这将导致更多的资本流入中国,并支持中国的资产价格。 对于股市,综合判断,我们认为牛市的基础依然健康;牛市可能即将或正在逐步转入“下半场”;2008年对市场最大的压力和不确定性将主要来自于信贷控制,将主要取决于信贷控制的力度和持续时间。
新浪声明:本版文章内容纯属作者个人观点,仅供投资者参考,并不构成投资建议。投资者据此操作,风险自担。 最牛散户亿元吃进中国铁建最牛散户亿元吃进中国铁建 三元管理层是吃shi 长大的一群饭桶1.你们管理层是不是吃干饭的?如果不是,那一定是吃^屎长大的一群饭桶!伊利复权价到过300~400元,连光明也到过30~40元,再看看三元的德行,作为管理层的你们难道就不感到丢人?除非你们都是婊子养的,对丢人的事习以为常!我们因为三元是首都的品牌、也相信你们一直宣传的所谓人民大会堂“御用奶”一定会比别的奶牛比,可是事实证明饭桶就是饭桶,加再多的帽子也没有用! 中国的股市中国的股市能有今天,中国的上市公司,中国的国有企业能走到今天,是谁的功劳,我告诉你们,是从1996年到现在几千万股民的血和泪堆出来的!上石化股改连续两次没成功,该公司管理层竟然说出"我们本来就不想流通,是为了支持股权分置改革......"的话来,我真想问:你MA的你们当初上市从股民手里圈钱的时候怎么不说这话? 3月14日 上海新编高中历史教科书目录上海新编教材范本系列之:高中历史教科书目录 3月13日 女子炒期货4万做到1450万后又变回5万女子炒期货4万做到1450万后又变回5万
http://www.sina.com.cn 2008年03月13日03:35 南方都市报
对于武汉女子万群(化名)而言,3月11日是她人生中永难忘怀的一天。作为“武昌女期民半年内从4万做到1450万”这一期市神话的主角,万群所持有的最后300手豆油合约因保证金不足于当日上午被强行平仓,其账户里最终剩下的资金不到5万元,一场千万富翁的“美梦”在持续了近半个月后,终告结束。 半年炒成千万富翁
据相关期货公司知情人士介绍,万群大约50岁上下年纪,退休之前的职业可能是教师。2005年7月,万群拿着6万元开始涉足期货市场,此前,她已有了10年的炒股经历。步入期市的头两年,万群的战绩并不出众,其保证金从最初的6万元缩水至4万元;直到去年下半年,她的交易账户才逐渐引起了期货公司的注意。
从2007年8月下旬起,万群开始重仓介入豆油期货合约,此后两三个月,豆油主力合约0805从7800元/吨起步,一路上扬至9700元/吨,截至当年11月中旬,万群已有10倍获利。进入2008年,豆油上涨速度越来越快,2月底,豆油0805已然逼近1.4万元/吨,也就是在那时,万群的账面保证金突破了1000万元,成为了名副其实的“千万富翁”。
采用股票手法炒期货
“她采取的是全仓操作的股票手法。”知情人士透露说,万群利用期货交易浮动盈利可以开新仓的特点,全线扑入豆油期货,越涨越买。这种操作方式最大程度地利用了杠杆,可以将利润放至最大;但与此同时,风险也被放大到了顶点,一旦行情有所调整,满仓交易的万群将面临灭顶之灾。
据悉,期货公司曾不止一次劝她降低仓位,但万群根本听不进去。事实上,万群之所以能够在半年内成为千万富翁,所仰仗的正是这种满仓交易,因此对她而言,这样做没有什么不对的地方。
风云突变却拒绝减仓
万群缔造的期市神话很快引起了媒体关注,“武昌女子半年内从4万做到1450万”的新闻频频见诸报端,并在网上广为转载。
“她的资金真正突破千万是在2月28日、29日。”知情人士告诉记者,当时正值豆油连续涨停阶段,万群账户的浮动权益在3月4日达到顶峰,最高时竟达2000多万元。不过,当天的行情出现剧烈震荡,油价在一个小时内从涨停快速滑落至跌停。
在豆油从涨停到跌停的过程中,万群的账户因为保证金不足,已经被强行平去了一部分合约,但这并没有引起她的重视。
“期货公司的人找她谈过,但她拒绝主动减仓。”不愿意透露姓名的相关人士表示,因为此前一些媒体已经报道了万群期货交易半年发迹的事情,很多人已经知道她,在这样的情况下,万群碍于面子,不愿意主动平仓,因为她知道,只要一卖,自己就不再是千万富翁了。“实际上,3月6日,她的账上至少还有几百万元,要平仓还是有机会的。”
被强行平仓回到起点
出于种种考虑,万群错过了最佳的减仓时机。3月7日和10日两天,豆油无量跌停,万群就是想平仓也平不了了,由于仓位过重,其巨大的账面盈利瞬间化为乌有。
“在下跌的时候,我们都不敢给她看相关的报纸,以免刺激她。”万群的丈夫在打电话到期货公司咨询情况时告诉工作人员。
3月11日上午,连续两个交易日无量跌停的豆油期货终于再打开停板。大连商品交易所豆油主力合约0805、0809盘中双双翻红,收盘分别下跌0.83%和0.36%.但由于没有能力追加保证金,万群所持有的最后300手合约被强行平仓,最终,她的账户保证金只剩下了不到5万元。《上海证券报》 3月12日 房价的一半被政府拿走“明天上午我们准备对北京东四环一个项目做实地考察,看看政府税费到底占房价多少,你们到时候一定来呀!”3月7日下午的一次政协经济组讨论会间隙,王超斌拍着记者的肩膀说。
作为全国政协委员、河南工商联副会长,王超斌进京参加“两会”前,就委托河南房地产协会做了一份“房价清单”。清单显示,政府各种税费占总房价的30%上下,再加上层层“公关费”,房价的一半被政府拿去了。结论是,地价在涨,税费在涨,如此下去,房价如何会降?
河南如此,北京的情况又怎样?3月8日是星期六,王超斌联合了十多名全国政协委员,利用休会时间一道到北京楼盘去“摸底”。
“不可预测费”
初次接触王超斌的人都觉得他风风火火,胆大敢为。
3月4日,温家宝总理来到政协经济组参与讨论。看到总理进门,王超斌第一个站起来,从第二排跑上第一排去和总理握手。
据当时在场者描述,总理走时,王超斌又是经济组中唯一一个坚持把总理一直送上车的,在短暂的途中,他一路给总理反映河南的发展情况。总理连连点头。
“政协委员就要反映民众意见最大的事。”王超斌对记者说,“房价这么高,到底是由什么构成的?开发商抬价是一方面,但把开发商整治了,房价是不是就能下来?”
王超斌在1990年代做过一段房地产开发,自称“深知里面政府乱收费之严重”,对房价的构成要认真分析和调研。
“我是一定要做这个事,开发商不肯接待,我去找人说说,”王超斌3月7日说,他要给北京房价来个“解剖麻雀”。
3月8日这天,王超斌一行来到位于北京东四环的“东区国际”项目。当着20多名记者的面,他要“东区国际”项目董事长刘玫“亮亮家底”。
刘玫报出一笔账:“东区国际”的地3年前拿下的,当时地价是900万/亩,现在那一带地价已经到了2000万元/亩。目前楼盘价格2.3万元/平方米,其中,土地成本约6000元/平方米,建筑成本约3500元/平方米,精装成本为4000元/平方米。剩下的主要就是各种税费,占了房价的15%-20%左右。
3月8日晚上6点半,王超斌等10余名政协委员在驻地京丰宾馆召开新闻发布会。王宣布说他已就当天调研的情况,综合河南房协的资料,写了一份<减少政府收费环节遏制房价上涨的建议>的提案。
王超斌在提案中说,各地政府在房地产开发过程中,除了土地出让金和双重配套费外,还要征收蓝图审查费、防雷检验费、防震检验费、施工合同鉴证费、绿化费、墙改费、施工放线费、规划咨询费、人防费、文物勘探费、预算审核费、工程造价咨询费、质量监督费、土壤氡气检测费、室内空气检测费、安全施工措施费、散装水泥推广费、预售许可证服务费、房屋面积界定费、房价审查服务费、管线综合竣工图设计费等50多项费用,涉及25个部门。
上述费用有的要开发商缴纳,有的要买房人缴纳。有的是“白收费”——政府收费后不提供相应服务,款项也去向不明。
比如“蓝图审查费”,开发商要将项目规划图纸给规划等部门审查,这些部门拿过图纸来简单看看(找到关系的就可以不看),就可以坐收几十万费用。
“绿化费”,名义上是政府部门向开发商收取后,拿来做项目及配套绿化建设所用。但多数情况下,费收了,绿化还是得开发商来做。
还有电力委托费,是项目施工期间,需要架设专门的电线和变压器以供应工地高耗电施工设备需要。但是多数情况下,一次性缴纳几万甚至十几万的委托费后,电力部门便不再来,工地上用电设备和变压器等还是要施工单位自己做。但是如果不交这笔钱,施工用电就没法保障。
再有教育附加费,“这个费用向开发商收合不合理先不讲,单说收了这么多年,钱是否用到教育上了?”王超斌说,国家早几年提出教育投入到2006年要占到GDP的4%,而眼下只有2.9%左右。这里面包不包括这笔“教育附加费”呢?不得而知。
王超斌说,所有房地产项目都要缴纳两次“配套费”:一次是土地配套费,是政府为土地做道路等市政配套建设所花的费用;二是建设配套费,指项目建设期间政府为项目所做的路、电、水等配套建设的费用。“配套费”价格约每平方米200元左右。
王超斌认为最不可思议的是清单上有一项“不可预测费”。据说该费用占到项目总造价的1%-2%,如果找找关系,可以少征,甚至不征。
除了地方政府征收的各类费用,房地产行业还要缴纳营业税、印花税、城建税、教育附加税、契税、土地增值税、所得税、土地使用税、房产税等,累计约占房价的15%。
其中有些属于重复征收,例如既开征土地使用税,又征房产税;既征收土地出让金、营业税和所得税,又再征收耕地使用税和土地增值税。
按照王超斌的计算,这些税费合计就占到房价的30%-35%。
“磕地”成本
税费只是明面上的,开发商反映说,从拿地、开工、预售、验收,整个开发链条的各个环节都要打点,“公关费”不比税费少。
开发商最难的是拿地。“磕地”已经成为业内的专用术语。一是形容非常难,磕头也未必给你;二是形容每拿一块地都要长时间公关。参加调研的一位政协委员告诉记者,单凭资金实力和开发能力来看,目前市场上出让的土地本来大多数会落入房地产上市公司之手。但是从北京市2006-2007年的土地出让结果来看,中小开发商拿地仍占多数。
这里面,就有“公关费”的一份作用。每一家生存下来的开发商都有一部非凡的“磕地史”。
“土地‘招拍挂’以前,我们在北京最豪华的会所包上一间房,长期招待那些掌握批地关键环节的官员,”一位不愿披露姓名的北京开发商老总说,“招拍挂”以后,混乱的公关现象得以减少,但公关“花的钱比以前更多了”。
“税费的征收是弹性的,跟官员关系好能拿到折扣,这就刺激开发商加大公关投入,公关费用最后打入房价,由买房人埋单。”和王超斌一道参加3月8日调研的全国政协委员金正新说。
“大家都只看到房价上涨,没看到背后各种税费和公关费用也在涨,根治房价需要全面下药。”另一位参与调研的政协委员向随行的记者说。 3月2日 EE笔试/面试题目集合分类--IC设计基础EE笔试/面试题目集合分类--IC设计基础
1、我们公司的产品是集成电路,请描述一下你对集成电路的认识,列举一些与集成电路 相关的内容(如讲清楚模拟、数字、双极型、CMOS、MCU、RISC、CISC、DSP、ASIC、FPGA等的概念)。(仕兰微面试题目) 2、FPGA和ASIC的概念,他们的区别。(未知) 答案:FPGA是可编程ASIC。 ASIC:专用集成电路,它是面向专门用途的电路,专门为一个用户设计和制造的。根据一个用户的特定要求,能以低研制成本,短、交货周期供货的全定制,半定制集成电路。与门阵列等其它ASIC(Application Specific IC)相比,它们又具有设计开发周期短、设计制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检验等优点 模拟电路 1、基尔霍夫定理的内容是什么?(仕兰微电子) 2、平板电容公式(C=εS/4πkd)。(未知) 3、最基本的如三极管曲线特性。(未知) 4、描述反馈电路的概念,列举他们的应用。(仕兰微电子) 5、负反馈种类(电压并联反馈,电流串联反馈,电压串联反馈和电流并联反馈);负反馈馈 的优点(降低放大器的增益灵敏度,改变输入电阻和输出电阻,改善放大器的线性和非线性失真,有效地扩展放大器的通频带,自动调节作用)(未知) 6、放大电路的频率补偿的目的是什么,有哪些方法?(仕兰微电子) 7、频率响应,如:怎么才算是稳定的,如何改变频响曲线的几个方法。(未知) 8、给出一个查分运放,如何相位补偿,并画补偿后的波特图。(凹凸) 9、基本放大电路种类(电压放大器,电流放大器,互导放大器和互阻放大器),优缺 点,特别是广泛采用差分结构的原因。(未知) 10、给出一差分电路,告诉其输出电压Y+和Y-,求共模分量和差模分量。(未知) 11、画差放的两个输入管。(凹凸) 12、画出由运放构成加法、减法、微分、积分运算的电路原理图。并画出一个晶体管级的 运放电路。(仕兰微电子) 13、用运算放大器组成一个10倍的放大器。(未知) 14、给出一个简单电路,让你分析输出电压的特性(就是个积分电路),并求输出端某点的 rise/fall时间。(Infineon笔试试题) 15、电阻R和电容C串联,输入电压为R和C之间的电压,输出电压分别为C上电压和R上电 压,要求绘制这两种电路输入电压的频谱,判断这两种电路何为高通滤波器,何为低通滤 波器。当RC<16、有源滤波器和无源滤波器的原理及区别?(新太硬件) 17、有一时域信号S=V0sin(2pif0t)+V1cos(2pif1t)+V2sin(2pif3t+90),当其通过低通、带通、高通滤波器后的信号表示方式。(未知) 18、选择电阻时要考虑什么?(东信笔试题) 19、在CMOS电路中,要有一个单管作为开关管精确传递模拟低电平,这个单管你会用P管 还是N管,为什么?(仕兰微电子) 20、给出多个mos管组成的电路求5个点的电压。(Infineon笔试试题) 21、电压源、电流源是集成电路中经常用到的模块,请画出你知道的线路结构,简单描述其优缺点。(仕兰微电子) 22、画电流偏置的产生电路,并解释。(凹凸) 23、史密斯特电路,求回差电压。(华为面试题) 24、晶体振荡器,好像是给出振荡频率让你求周期(应该是单片机的,12分之一周期....) (华为面试题) 25、LC正弦波振荡器有哪几种三点式振荡电路,分别画出其原理图。(仕兰微电子) 26、VCO是什么,什么参数(压控振荡器?) (华为面试题) 27、锁相环有哪几部分组成?(仕兰微电子) 28、锁相环电路组成,振荡器(比如用D触发器如何搭)。(未知) 29、求锁相环的输出频率,给了一个锁相环的结构图。(未知) 30、如果公司做高频电子的,可能还要RF知识,调频,鉴频鉴相之类,不一一列举。(未 知) 31、一电源和一段传输线相连(长度为L,传输时间为T),画出终端处波形,考虑传输线 无损耗。给出电源电压波形图,要求绘制终端波形图。(未知) 32、微波电路的匹配电阻。(未知) 33、DAC和ADC的实现各有哪些方法?(仕兰微电子) 34、A/D电路组成、工作原理。(未知) 35、实际工作所需要的一些技术知识(面试容易问到)。如电路的低功耗,稳定,高速如何 做到,调运放,布版图注意的地方等等,一般会针对简历上你所写做过的东西具体问,肯定会问得很细(所以别把什么都写上,精通之类的词也别用太多了),这个东西各个人就不一样了,不好说什么了。(未知) _______________________________________________________________________
数字电路 1、同步电路和异步电路的区别是什么?(仕兰微电子) 2、什么是同步逻辑和异步逻辑?(汉王笔试) 同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。 3、什么是"线与"逻辑,要实现它,在硬件特性上有什么具体要求?(汉王笔试) 线与逻辑是两个输出信号相连可以实现与的功能。在硬件上,要用oc门来实现,由于不用oc门可能使灌电流过大,而烧坏逻辑门。 同时在输出端口应加一个上拉电阻。 4、什么是Setup 和Holdup时间?(汉王笔试) 5、setup和holdup时间,区别.(南山之桥) 6、解释setup time和hold time的定义和在时钟信号延迟时的变化。(未知) 7、解释setup和hold time violation,画图说明,并说明解决办法。(威盛VIA2003.11.06 上海笔试试题) Setup/hold time 是测试芯片对输入信号和时钟信号之间的时间要求。建立时间是指触发器的时钟信号上升沿到来以前,数据稳定不变的时间。输入信号应提前时钟上升沿(如上升沿有效)T时间到达芯片,这个T就是建立时间-Setup time.如不满足setup time,这个数据就不能被这一时钟打入触发器,只有在下一个时钟上升沿,数据才能被打入触发器。保持时间是指触发器的时钟信号上升沿到来以后,数据稳定不变的时间。如果hold time不够,数据同样不能被打入触发器。建立时间(Setup Time)和保持时间(Hold time)。建立时间是指在时钟边沿前,数据信号需要保持不变的时间。保持时间是指时钟跳变边沿后数据信号需要保持不变的时间。如果不满足建立和保持时间的话,那么DFF将不能正确地采样到数据,将会出现 metastability的情况。如果数据信号在时钟沿触发前后持续的时间均超过建立和保持时间,那么超过量就分别被称为建立时间裕量和保持时间裕量。 8、说说对数字逻辑中的竞争和冒险的理解,并举例说明竞争和冒险怎样消除。(仕兰微电子) 9、什么是竞争与冒险现象?怎样判断?如何消除?(汉王笔试) 在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决 方法:一是添加布尔式的消去项,二是在芯片外部加电容。 10、你知道那些常用逻辑电平?TTL与COMS电平可以直接互连吗?(汉王笔试) 常用逻辑电平:12V,5V,3.3V;TTL和CMOS不可以直接互连,由于TTL是在0.3-3.6V之间,而CMOS则是有在12V的有在5V的。CMOS输出接到TTL是可以直接互连。TTL接CMOS需要在输出端口加一上拉电阻接到5V或者12V。 11、如何解决亚稳态。(飞利浦-大唐笔试) 亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平 上。在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无 用的输出电平可以沿信号通道上的各个触发器级联式传播下去。 12、IC设计中同步复位与 异步复位的区别。(南山之桥) 13、MOORE 与 MEELEY状态机的特征。(南山之桥) 14、多时域设计中,如何处理信号跨时域。(南山之桥) 15、给了reg的setup,hold时间,求中间组合逻辑的delay范围。(飞利浦-大唐笔试) Delay < period - setup – hold 16、时钟周期为T,触发器D1的建立时间最大为T1max,最小为T1min。组合逻辑电路最大延迟为T2max,最小为T2min。问,触发器D2的建立时间T3和保持时间应满足什么条件。(华为) 17、给出某个一般时序电路的图,有Tsetup,Tdelay,Tck->q,还有 clock的delay,写出决定最大时钟的因素,同时给出表达式。(威盛VIA 2003.11.06 上海笔试试题) 18、说说静态、动态时序模拟的优缺点。(威盛VIA 2003.11.06 上海笔试试题) 19、一个四级的Mux,其中第二级信号为关键信号 如何改善timing。(威盛VIA 2003.11.06 上海笔试试题) 20、给出一个门级的图,又给了各个门的传输延时,问关键路径是什么,还问给出输入,使得输出依赖于关键路径。(未知) 21、逻辑方面数字电路的卡诺图化简,时序(同步异步差异),触发器有几种(区别,优 点),全加器等等。(未知) 22、卡诺图写出逻辑表达使。(威盛VIA 2003.11.06 上海笔试试题) 23、化简F(A,B,C,D)= m(1,3,4,5,10,11,12,13,14,15)的和。(威盛) 24、please show the CMOS inverter schmatic,layout and its cross sectionwith P-well process.Plot its transfer curve (Vout-Vin) And also explain the operation region of PMOS and NMOS for each segment of the transfer curve? (威盛笔试题circuit design-beijing-03.11.09) 25、To design a CMOS invertor with balance rise and fall time,please define the ration of channel width of PMOS and NMOS and explain? 26、为什么一个标准的倒相器中P管的宽长比要比N管的宽长比大?(仕兰微电子) 27、用mos管搭出一个二输入与非门。(扬智电子笔试) 28、please draw the transistor level schematic of a cmos 2 input AND gate and explain which input has faster response for output rising edge.(less delay time)。(威盛笔试题circuit design-beijing-03.11.09) 29、画出NOT,NAND,NOR的符号,真值表,还有transistor level的电路。(Infineon笔 试) 30、画出CMOS的图,画出tow-to-one mux gate。(威盛VIA 2003.11.06 上海笔试试题) 31、用一个二选一mux和一个inv实现异或。(飞利浦-大唐笔试) 32、画出Y=A*B+C的cmos电路图。(科广试题) 33、用逻辑们和cmos电路实现ab+cd。(飞利浦-大唐笔试) 34、画出CMOS电路的晶体管级电路图,实现Y=A*B+C(D+E)。(仕兰微电子) 35、利用4选1实现F(x,y,z)=xz+yz'。(未知) 36、给一个表达式f=xxxx+xxxx+xxxxx+xxxx用最少数量的与非门实现(实际上就是化 简)。 37、给出一个简单的由多个NOT,NAND,NOR组成的原理图,根据输入波形画出各点波形。 (Infineon笔试) 38、为了实现逻辑(A XOR B)OR (C AND D),请选用以下逻辑中的一种,并说明为什 么?1)INV 2)AND 3)OR 4)NAND 5)NOR 6)XOR 答案:NAND(未知) 39、用与非门等设计全加法器。(华为) 40、给出两个门电路让你分析异同。(华为) 41、用简单电路实现,当A为输入时,输出B波形为…(仕兰微电子) 42、A,B,C,D,E进行投票,多数服从少数,输出是F(也就是如果A,B,C,D,E中1的个数比0多,那么F输出为1,否则F为0),用与非门实现,输入数目没有限制。(未知) 43、用波形表示D触发器的功能。(扬智电子笔试) 44、用传输门和倒向器搭一个边沿触发器。(扬智电子笔试) 45、用逻辑们画出D触发器。(威盛VIA 2003.11.06 上海笔试试题) 46、画出DFF的结构图,用verilog实现之。(威盛) 47、画出一种CMOS的D锁存器的电路图和版图。(未知) 48、D触发器和D锁存器的区别。(新太硬件面试) 49、简述latch和filp-flop的异同。(未知) 50、LATCH和DFF的概念和区别。(未知) 51、latch与register的区别,为什么现在多用register.行为级描述中latch如何产生的。(南山之桥) 52、用D触发器做个二分颦的电路.又问什么是状态图。(华为) 53、请画出用D触发器实现2倍分频的逻辑电路?(汉王笔试) 54、怎样用D触发器、与或非门组成二分频电路?(东信笔试) 55、How many flip-flop circuits are needed to divide by 16? (Intel) 16分频? 56、用filp-flop和logic-gate设计一个1位加法器,输入carryin和current-stage,输出carryout和next-stage. (未知) 57、用D触发器做个4进制的计数。(华为) 58、实现N位Johnson Counter,N=5。(南山之桥) 59、用你熟悉的设计方式设计一个可预置初值的7进制循环计数器,15进制的呢?(仕兰微电子) 60、数字电路设计当然必问Verilog/VHDL,如设计计数器。(未知) 61、BLOCKING NONBLOCKING 赋值的区别。(南山之桥) 65、请用HDL描述四位的全加法器、5分频电路。(仕兰微电子) 66、用VERILOG或VHDL写一段代码,实现10进制计数器。(未知) 67、用VERILOG或VHDL写一段代码,实现消除一个glitch。(未知) 68、一个状态机的题目用verilog实现(不过这个状态机画的实在比较差,很容易误解 的)。(威盛VIA 2003.11.06 上海笔试试题) 69、描述一个交通信号灯的设计。(仕兰微电子) 70、画状态机,接受1,2,5分钱的卖报机,每份报纸5分钱。(扬智电子笔试) 71、设计一个自动售货机系统,卖soda水的,只能投进三种硬币,要正确的找回钱 数。 (1)画出fsm(有限状态机);(2)用verilog编程,语法要符合fpga设计的要求。(未知) 72、设计一个自动饮料售卖机,饮料10分钱,硬币有5分和10分两种,并考虑找零:(1) 画出fsm(有限状态机);(2)用verilog编程,语法要符合fpga设计的要求;(3)设计 工程中可使用的工具及设计大致过程。(未知) 73、画出可以检测10010串的状态图,并verilog实现之。(威盛) 74、用FSM实现101101的序列检测模块。(南山之桥) a为输入端,b为输出端,如果a连续输入为1101则b输出为1,否则为0。 例如a: 0001100110110100100110 b: 0000000000100100000000 请画出state machine;请用RTL描述其state machine。(未知) 78、sram,falsh memory,及dram的区别?(新太硬件面试) 79、给出单管DRAM的原理图(西电版《数字电子技术基础》作者杨颂华、冯毛官205页图9 -14b),问你有什么办法提高refresh time,总共有5个问题,记不起来了。(降低温 度,增大电容存储容量)(Infineon笔试) 81、名词:sram,ssram,sdram 名词IRQ,BIOS,USB,VHDL,SDR IRQ: Interrupt ReQuest BIOS: Basic Input Output System USB: Universal Serial Bus VHDL: VHIC Hardware Description Language SDR: Single Data Rate 压控振荡器的英文缩写(VCO)。 动态随机存储器的英文缩写(DRAM)。 名词解释,无聊的外文缩写罢了,比如PCI、ECC、DDR、interrupt、pipeline、 IRQ,BIOS,USB,VHDL,VLSI VCO(压控振荡器) RAM (动态随机存储器),FIR IIR DFT(离散 傅立叶变换)或者是中文的,比如:a.量化误差 b.直方图 c.白平衡 ____________________________________________________________________________
IC设计基础(流程、工艺、版图、器件) 1、我们公司的产品是集成电路,请描述一下你对集成电路的认识,列举一些与集成电路 相关的内容 (如讲清楚模拟、数字、双极型、CMOS、MCU(MCU(MicroControllerUnit)中文名称为多点控制单元,又称单片微型计算机(SingleChipMicrocomputer),是指随着大规模集成电路的出现及其发展,将计算机的CPU、RAM、ROM、定时数器和多种I/O接口集成在一片芯片上,形成芯片级的计算机,为不同的应用场合做不同组合控制。 MCU的分类 MCU按其存储器类型可分为MASK(掩模)ROM、OTP(一次性可编程)ROM、FLASHROM等类型。MASKROM的MCU价格便宜,但程序在出厂时已经固化,适合程序固定不变的应用场合;FALSHROM的MCU程序可以反复擦写,灵活性很强,但价格较高,适合对价格不敏感的应用场合或做开发用途;OTPROM的MCU价格介于前两者之间,同时又拥有一次性可编程能力,适合既要求一定灵活性,又要求低成本的应用场合,尤其是功能不断翻新、需要迅速量产的电子产品。微控制器在经过这几年不断地研究,发展,历经4位,8位,到现在的16位及32位,甚至64位。产品的成熟度,以及投入厂商之多,应用范围之广,真可谓之空前。目前在国外大厂因开发较早,产品线广,所以技术领先,而本土厂商则以多功能为产品导向取胜。但不可讳言的,本土厂商的价格战是对外商造成威胁的关键因素。由于制程的改进,8位MCU与4位MCU价差相去无几,8位已渐成为市场主流;目前4位MCU大部份应用在计算器、车用仪表、车用防盗装置、呼叫器、无线电话、CD播放器、LCD驱动控制器、LCD游戏机、儿童玩具、磅秤、充电器、胎压计、温湿度计、遥控器及傻瓜相机等;8位MCU大部份应用在电表、马达控制器、电动玩具机、变频式冷气机、呼叫器、传真机、来电辨识器(CallerID)、电话录音机、CRT显示器、键盘及USB等;16位MCU大部份应用在行动电话、数字相机及摄录放影机等;32位MCU大部份应用在Modem、GPS、PDA、HPC、STB、Hub、Bridge、Router、工作站、ISDN电话、激光打印机与彩色传真机;64位MCU大部份应用在高阶工作站、多媒体互动系统、高级电视游乐器(如SEGA的Dreamcast及Nintendo的GameBoy)及高级终端机等)、RISC(RISC是什么含义?它有什么特点?简称为精简指令系统计算机(简称RISC),起源于80年代的MIPS主机(即RISC机),RISC机中采用的微处理器统称RISC处理器。 RISC典型范例如:MIPS R3000、HP—PA8000系列,Motorola M88000等均属于RISC微处理器。 RISC主要特点: RISC微处理器不仅精简了指令系统,采用超标量和朝流水线结构;它们的指令数目只有几十条,却大大增强了并行处理能力。如:1987年Sun Microsystem公司推出的SPARC芯片就是一种超标量结构的RISC处理器。而SGI公司推出的MIPS处理器则采用超流水线结构,这些RISC处理器在构建并行精简指令系统多处理机中起着核心的作用。RISC处理器是当今UNIX领域64位多处理机的主流芯片 性能特点一:由于指令集简化后,流水线以及常用指令均可用硬件执行;性能特点二:采用大量的寄存器,使大部分指令操作都在寄存器之间进行,提高了处理速度;性能特点三:采用缓存—主机—外存三级存储结构,使取数与存数指令分开执行,使处理器可以完成尽可能多的工作,且不因从存储器存取信息而放慢处理速度。应用特点;由于RISC处理器指令简单、采用硬布线控制逻辑、处理能力强、速度快,世界上绝大部分UNIX工作站和服务器厂商均采用RISC芯片作CPU用。如原DEC的Alpha21364、IBM的Power PC G4、HP的PA—8900、SGI的R12000A和SUN Microsystem公司的Ultra SPARC ║。运行特点: RISC芯片的工作频率一般在400MHZ数量级。时钟频率低,功率消耗少,温升也少,机器不易发生故障和老化,提高了系统的可靠性。单一指令周期容纳多部并行操作。在RISC微处理器发展过程中。曾产生了超长指令字(VLIW)微处理器,它使用非常长的指令组合,把许多条指令连在一起,以能并行执行。VLIW处理器的基本模型是标量代码的执行模型,使每个机器周期内有多个操作。有些RISC处理器中也采用少数VLIW指令来提高处理速度。)、 CISC(CISC(复杂指令集计算机)和RISC(精简指令集计算机)是前CPU 的两种架构。它们的区别在于不同的CPU设计理念和方法。早期的CPU全部是CISC架构,它的设计目的是要用最少的机器语言指令来完成所需的计算任务。 RISC则是计算机系统只有少数指令,但是每个指令的执行时间相当短,因此CPU可以用相当高的频率来运算。)、DSP(DSP是单片机的一个分支。它有专门的FFT算法需要的特殊指令,流水线指令处理。能以较高的速度进行运算。我们可以根据需要选用他。如果你作一个遥控器,选用他就没优势了。因为很多其他的用于遥控的单片机比他更适合用来作遥控器。如果你用89C51来作语音或图像识别就不如DSP了。一个产品的设计要考虑,在满足需求的情况下,他的性价比。 2,单片机长于控制场合应用,DSP长于信号分析运算,本身针对了不同的需求,应该不存在互相替代的问题。不过目前这两者特点互相融合的趋势倒是越来越明显。3,如果你还没进入开发领域,把单片机的硬件摸透了对学DSP帮助很大,如果你还没学单片机把起点架在DSP上也没问题,以我的心得单片机你迟早要遇到,不如先学好他,对单片机能解决的问题,DSP的开发成本大得多,不过你将来要是遇到复杂的数字信号处理(如IIR,FIR,FFT)等,就用得上他了,它的速度和实时处理能力单片机是望尘莫及的。还有一篇文章讲这个的: DSP器件与单片机的比较在过去的几十年里,单片机的广泛应用实现了简单的智能控制功能。随着信息化的进程和计算机科学与技术、信号处理理论与方法等的迅速发展,需要处理的数据量越来越大,对实时性和精度的要求越来越高,在某些领域,低档单片机已不再能满足要求。近年来,各种集成化的单片DSP的性能得到很大改善,软件和开发工具也越来越多,越来越好;价格却大幅度下滑,从而使得DSP器件及技术更容易使用,价格也能够为广大用户接受;越来越多的单片机用户开始考虑选用DSP器件来提高产品性能,DSP器件取代高档单片机的可能性越来越大。本文将从性能、价格等方面对单片机和DSP器件进行比较,在此基础上,以TI的MS320C2XX系列DSP器件为例,探讨DSP器件取代高档单片机的可行性。1.单片机的特点所谓单片机就是在一块芯片上集成了CPU、RAM、ROM(EPROM或EEPROM)、时钟、定时/计数器、多种功能的串行和并行I/O口。如Intel公司的8031系列等。除了以上基本功能外,有的还集成有A/D、D/A,如Intel公司的8098系列。概括起来说,单片机具有如下特点:具有位处理能力,强调控制和事务处理功能。价格低廉。如低档单片机价格只有人民币几元钱。开发环境完备,开发工具齐全,应用资料众多。后备人才充足。国内大多数高校都开设了单片机课程和单片机实验。 2.DSP器件的特点 与单片机相比,DSP器件具有较高的集成度。DSP具有更快的CPU,更大容量的存储器,内置有波特率发生器和FIFO缓冲器。提供高速、同步串口和标准异步串口。有的片内集成了A/D和采样/保持电路,可提供PWM输出。DSP器件采用改进的哈佛结构,具有独立的程序和数据空间,允许同时存取程序和数据。内置高速的硬件乘法器,增强的多级流水线,使DSP器件具有高速的数据运算能力。DSP器件比16位单片机单指令执行时间快8~10倍,完成一次乘加运算快16~30倍。DSP器件还提供了高度专业化的指令集,提高了FFT快速傅里叶变换和滤波器的运算速度。此外,DSP器件提供JTAG接口,具有更先进的开发手段,批量生产测试更方便,开发工具可实现全空间透明仿真,不占用用户任何资源。软件配有汇编/链接C编译器、C源码调试器。目前国内推广应用最为广泛的DSP器件是美国德州仪器(TI)公司生产的TMS320系列。DSP开发系统的国产化工作已经完成,国产开发系统的价格至少比进口价格低一半,有的如TMS320C2XX开发系统只有进口开发系统价格的1/5,这大大刺激了DSP器件的应用。目前,已有不少高校计划建立DSP实验室,TI公司和北京闻亭公司都已制订了高校支持计划,将带动国内DSP器件的应用和推广(哈尔滨工程大学就是其中的一所,他们的实力非常强大) 3.DSP器件大规模推广指日可待?通过上述比较,我们可得出结论:DSP器件是一种具有高速运算能力的单片机。从应用角度看:DSP器件是运算密集型的,而单片机是事务密集型的,DSP器件可以取代单片机,单片机却不能取代DSP。DSP器件价格大幅度下滑,直逼单片机?DSP器件广泛使用了JTAG硬件仿真,比单片机更易于硬件调试。国产化的DSP开发系统为更多用户采用DSP器件提供了可能性。DSP取代单片机的技术和价格的市场条件已经成熟?大规模推广指日可待?(现在吹牛的人真是一点草稿都不打。不过DSP确实功能够强大。)结论:使用单片机的不一定了解DSP,并且非要用DSP不可;但使用DSP的一定了解单片机,并且能做出性价比高的产品。)、ASIC、FPGA(ASIC(Application Specific Intergrated Circuits)即专用集成电路,是指应特定用户要求和特定电子系统的需要而设计、制造的集成电路。目前用CPLD(复杂可编程逻辑器件)和FPGA(现场可编程逻辑阵列)来进行ASIC设计是最为流行的方式之一,它们的共性是都具有用户现场可编程特性,都支持边界扫描技术,但两者在集成度、速度以及编程方式上具有各自的特点。ASIC的特点是面向特定用户的需求,品种多、批量少,要求设计和生产周期短,它作为集成电路技术与特定用户的整机或系统技术紧密结合的产物,与通用集成电路相比具有体积更小、重量更轻、功耗更低、可靠性提高、性能提高、保密性增强、成本降低等优点。 FPGA(现场可编程门阵列)是专用集成电路(ASIC)中集成度最高的一种,用户可对FPGA内部的逻辑模块和I/O模块重新配置,以实现用户的逻辑,因而也被用于对CPU的模拟。用户对FPGA的编程数据放在Flash芯片中,通过上电加载到FPGA中,对其进行初始化。也可在线对其编程,实现系统在线重构,这一特性可以构建一个根据计算任务不同而实时定制的CPU,这是当今研究的热门领域。 电子封装是集成电路芯片生产完成后不可缺少的 一道工序,是器件到系统的桥梁。所以FPGA是封装结构的是正确的!! )等的概念)。(仕兰微面试题目) 2、FPGA和ASIC的概念,他们的区别。(未知) 答案:FPGA是可编程ASIC。 ASIC:专用集成电路,它是面向专门用途的电路,专门为一个用户设计和制造的。根据一 个用户的特定要求,能以低研制成本,短、交货周期供货的全定制,半定制集成电路。与 门阵列等其它ASIC(Application Specific IC)相比,它们又具有设计开发周期短、设计制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检验等优点 3、什么叫做OTP片(OTP(一次性可编程))、掩膜片,两者的区别何在?(仕兰微面试题目) OTP与掩膜 OTP是一次性写入的单片机。过去认为一个单片机产品的成熟是以投产掩膜型单片机为标志的。由于掩膜需要一定的生产周期,而OTP型单片机价格不断下降,使得近年来直接使用OTP完成最终产品制造更为流行。它较之掩膜具有生产周期短、风险小的特点。近年来,OTP型单片机需量大幅度上扬,为适应这种需求许多单片机都采用了在片编程技术(In System Programming)。未编程的OTP芯片可采用裸片Bonding技术或表面贴技术,先焊在印刷板上,然后通过单片机上引出的编程线、串行数据、时钟线等对单片机编程。解决了批量写OTP 芯片时容易出现的芯片与写入器接触不好的问题。使OTP的裸片得以广泛使用,降低了产品的成本。编程线与I/O线共用,不增加单片机的额外引脚。而一些生产厂商推出的单片机不再有掩膜型,全部为有ISP功能的OTP。 4、你知道的集成电路设计的表达方式有哪几种?(仕兰微面试题目) 5、描述你对集成电路设计流程的认识。(一般来说asic和fpga/cpld没有关系!fpga是我们在小批量或者实验中采用的,生活中的电子器件上很少见到的。而asic是通过掩膜的高的,它是不可被修改的。至于流程,应该是前端、综合、仿真、后端、检查、加工、测试、封装。 我是做路由器asic设计的可能你上网用的网卡还有路由器就是我们公司的,呵呵,流程基本如此!)(仕兰微面试题目) 6、简述FPGA等可编程逻辑器件设计流程。 通常可将FPGA/CPLD设计流程归纳为以下7个步骤,这与ASIC设计有相似之处。 1.设计输入。在传统设计中,设计人员是应用传统的原理图输入方法来开始设计的。自90年代初, Verilog、VHDL、AHDL等硬件描述语言的输入方法在大规模设计中得到了广泛应用。 2.前仿真(功能仿真)。设计的电路必须在布局布线前验证电路功能是否有效。(ASCI设计中,这一步骤称为第一次Sign-off)PLD设计中,有时跳过这一步。 3.设计编译。设计输入之后就有一个从高层次系统行为设计向门级逻辑电路设转化翻译过程,即把设计输入的某种或某几种数据格式(网表)转化为软件可识别的某种数据格式(网表)。 4.优化。对于上述综合生成的网表,根据布尔方程功能等效的原则,用更小更快的综合结果代替一些复杂的单元,并与指定的库映射生成新的网表,这是减小电路规模的一条必由之路。 5.布局布线。在PLD设计中,3-5步可以用PLD厂家提供的开发软件(如 Maxplus2)自动一次完成。 6.后仿真(时序仿真)需要利用在布局布线中获得的精确参数再次验证电路的时序。(ASCI设计中,这一步骤称为第二次Sign—off)。 7.生产。布线和后仿真完成之后,就可以开始ASCI或PLD芯片的投产 )(仕兰微面试题目) 7、IC设计前端到后端的流程和eda工具。 (ic卡是集成电路卡的意思,ic卡是一种内藏大规模集成电路的塑料卡片,其大小和原来的磁卡电话的磁卡大小相同。 ic卡通常可分为存储卡、加密卡和智能卡三类,存储卡是可以直接对其进行读、写操作的存储器,加密卡是在存储卡的基础上增加了读、写加密功能,对加密卡进行操作时,必须首先核对卡中的密码,密码正确才能进行正常操作,智能卡是带有微处理器(cpu),同时也称作cpu卡。 ic卡的设计的流程分为:逻辑设计--子功能分解--详细时序框图--分块逻辑仿真--电路设计(RTL级描述)--功能仿真--综合(加时序约束和设计库)--电路网表--网表仿真)-预布局布线(SDF文件)--网表仿真(带延时文件)--静态时序分析--布局布线--参数提取--SDF文件--后仿真--静态时序分析--测试向量生成--工艺设计与生产--芯片测试--芯片应用,在验证过程中出现的时序收敛,功耗,面积问题,应返回前端的代码输入进行重新修改,再仿真,再综合,再验证,一般都要反复好几次才能最后送去foundry厂流片。)(未知) 9、Asic的design flow(设计流程)。(威盛VIA 2003.11.06 上海笔试试题)() 11、集成电路前段设计流程,写出相关的工具。(扬智电子笔试) 先介绍下IC开发流程: 1.)代码输入(design input) 用vhdl或者是verilog语言来完成器件的功能描述,生成hdl代码 语言输入工具:SUMMIT VISUALHDL MENTOR RENIOR 图形输入: composer(cadence); viewlogic (viewdraw) 2.)电路仿真(circuit simulation) 将vhd代码进行先前逻辑仿真,验证功能描述是否正确 数字电路仿真工具: Verolog: CADENCE Verolig-XL SYNOPSYS VCS MENTOR Modle-sim VHDL : CADENCE NC-vhdl SYNOPSYS VSS MENTOR Modle-sim 模拟电路仿真工具: ***ANTI HSpice pspice,spectre micro microwave: eesoft : hp 3.)逻辑综合(synthesis tools)
逻辑综合工具可以将设计思想vhd代码转化成对应一定工艺手段的门级电路;将初级仿真中所没有考虑的门沿(gates delay)反标到生成的门级网表中,返回电路仿真阶段进行再仿真。最终仿真结果生成的网表称为物理网表。 12、请简述一下设计后端的整个流程?(仕兰微面试题目) 13、是否接触过自动布局布线?请说出一两种工具软件。自动布局布线需要哪些基本元 素?(仕兰微面试题目)Protel Protel99是基于Win95/Win NT/Win98/Win2000的纯32位电路设计制版系统。Protel99提供了一个集成的设计环境,包括了原理图设计和PCB布线工具,集成的设计文档管理,支持通过网络进行工作组协同设计功能。 14、描述你对集成电路工艺的认识。(仕兰微面试题目)集成电路是采用半导体制作工艺,在一块较小的单晶硅片上制作上许多晶体管及电阻器、电容器等元器件,并按照多层布线或遂道布线的方法将元器件组合成完整的电子电路。它在电路中用字母“IC”(也有用文字符号“N”等)表示。 (一)按功能结构分类集成电路按其功能、结构的不同,可以分为模拟集成电路和数字集成电路两大类。 模拟集成电路用来产生、放大和处理各种模拟信号(指幅度随时间边疆变化的信号。例如半导体收音机的音频信号、录放机的磁带信号等),而数字集成电路用来产生、放大和处理各种数字信号(指在时间上和幅度上离散取值的信号。例如VCD、DVD重放的音频信号和视频信号)。 (二)按制作工艺分类 集成电路按制作工艺可分为半导体集成电路和薄膜集成电路。膜集成电路又分类厚膜集成电路和薄膜集成电路。 (三)按集成度高低分类 集成电路按集成度高低的不同可分为小规模集成电路、中规模集成电路、大规模集成电路和超大规模集成电路。(四)按导电类型不同分类 集成电路按导电类型可分为双极型集成电路和单极型集成电路。 双极型集成电路的制作工艺复杂,功耗较大,代表集成电路有TTL、ECL、HTL、LST-TL、STTL等类型。单极型集成电路的制作工艺简单,功耗也较低,易于制成大规模集成电路,代表集成电路有CMOS、NMOS、PMOS等类型。 (五)按用途分类 集成电路按用途可分为电视机用集成电路。音响用集成电路、影碟机用集成电路、录像机用集成电路、电脑(微机)用集成电路、电子琴用集成电路、通信用集成电路、照相机用集成电路、遥控集成电路、语言集成电路、报警器用集成电路及各种专用集成电路。 电视机用集成电路包括行、场扫描集成电路、中放集成电路、伴音集成电路、彩色解码集成电路、AV/TV转换集成电路、开关电源集成电路、遥控集成电路、丽音解码集成电路、画中画处理集成电路、微处理器(CPU)集成电路、存储器集成电路等。 音响用集成电路包括AM/FM高中频电路、立体声解码电路、音频前置放大电路、音频运算放大集成电路、音频功率放大集成电路、环绕声处理集成电路、电平驱动集成电路、电子音量控制集成电路、延时混响集成电路、电子开关集成电路等。 影碟机用集成电路有系统控制集成电路、视频编码集成电路、MPEG解码集成电路、音频信号处理集成电路、音响效果集成电路、RF信号处理集成电路、数字信号处理集成电路、伺服集成电路、电动机驱动集成电路等。 录像机用集成电路有系统控制集成电路、伺服集成电路、驱动集成电路、音频处理集成电路、视频处理集成电路。 15、列举几种集成电路典型工艺。工艺上常提到0.25,0.18指的是什么?(仕兰微面试题 目)制造工艺:我们经常说的0.18微米、0.13微米制程,就是指制造工艺了。制造工艺直接关系到cpu的电气性能。而0.18微米、0.13微米这个尺度就是指的是cpu核心中线路的宽度。线宽越小,cpu的功耗和发热量就越低,并可以工作在更高的频率上了。所以以前0.18微米的cpu最高的频率比较低,用0.13微米制造工艺的cpu会比0.18微米的制造工艺的发热量低都是这个道理了。 cd 16、请描述一下国内的工艺现状。(仕兰微面试题目) 17、半导体工艺中,掺杂有哪几种方式?(仕兰微面试题目) 根据掺入的杂质不同,杂质半导体可以分为N型和P型两大类。 N型半导体中掺入的杂质为磷等五价元素,磷原子在取代原晶体结构中的原子并构成共价键时,多余的第五个价电子很容易摆脱磷原子核的束缚而成为自由电子,于是半导体中的自由电子数目大量增加,自由电子成为多数载流子,空穴则成为少数载流子。P型半导体中掺入的杂质为硼或其他三价元素,硼原子在取代原晶体结构中的原子并构成共价键时,将因缺少一个价电子而形成一个空穴,于是半导体中的空穴数目大量增加,空穴成为多数载流子,而自由电子则成为少数载流子。 18、描述CMOS电路中闩锁效应产生的过程及最后的结果? Latch-up 闩锁效应,又称寄生PNPN效应或可控硅整流器( SCR, Silicon Controlled Rectifier )效应。在整体硅的CMOS管下,不同极性搀杂的区域间都会构成P-N结,而两个靠近的反方向的P-N结就构成了一个双极型的晶体三极管。因此CMOS管的下面会构成多个三极管,这些三极管自身就可能构成一个电路。这就是MOS管的寄生三极管效应。如果电路偶尔中出现了能够使三极管开通的条件,这个寄生的电路就会极大的影响正常电路的运作,会使原本的MOS电路承受比正常工作大得多的电流,可能使电路迅速的烧毁。Latch-up状态下器件在电源与地之间形成短路,造成大电流、EOS(电过载)和器件损坏。(仕兰微面试题目) 19、解释latch-up现象和Antenna effect和其预防措施.(未知) 20、什么叫Latchup? 闩锁效应,又称寄生PNPN效应或可控硅整流器( SCR, Silicon Controlled Rectifier )效应。 (科广试题) 21、什么叫窄沟效应? 当JFET或MESFET沟道较短,<1um的情况下,这样的器件沟道内电场很高,载流子民饱合速度通过沟道,因而器件的工作速度得以提高,载流子漂移速度,通常用分段来描述,认为电场小于某一临界电场时,漂移速度与近似与电场强成正比,迁移率是常数,当电场高于临界时,速度饱和是常数。所以在短沟道中,速度是饱和的,漏极电流方程也发生了变化,,这种由有况下饱和电流不是由于沟道夹断引起的而是由于速度饱和,,别名(科广试题) 22、什么是NMOS、PMOS、CMOS?什么是增强型、耗尽型?什么是PNP、NPN?他们有什么差别?(仕兰微面试题目) 23、硅栅COMS工艺中N阱中做的是P管还是N管,N阱的阱电位的连接有什么要求?(仕兰微面试题目) 24、画出CMOS晶体管的CROSS-OVER图(应该是纵剖面图),给出所有可能的传输特性和转移特性。(Infineon笔试试题) 25、以interver为例,写出N阱CMOS的process流程,并画出剖面图。(科广试题) 26、Please explain how we describe the resistance in semiconductor. Compare the resistance of a metal,poly and diffusion in tranditional CMOS process.(威盛笔试题circuit design-beijing-03.11.09) 27、说明mos一半工作在什么区。(凹凸的题目和面试) 28、画p-bulk 的nmos截面图。(凹凸的题目和面试) 29、写schematic note(?), 越多越好。(凹凸的题目和面试) 30、寄生效应在ic设计中怎样加以克服和利用。(未知) 31、太底层的MOS管物理特性感觉一般不大会作为笔试面试题,因为全是微电子物理,公式推导太罗索,除非面试出题的是个老学究。IC设计的话需要熟悉的软件: Cadence, Synopsys, Avant,UNIX当然也要大概会操作。 32、unix 命令cp -r, rm,uname。(扬智电子笔试) ___________________________________________________________________________
单片机、MCU、计算机原理 1、简单描述一个单片机系统的主要组成模块,并说明各模块之间的数据流流向和控制流 流向。简述单片机应用系统的设计原则。(仕兰微面试题目) 2、画出8031与2716(2K*8ROM)的连线图,要求采用三-八译码器,8031的P2.5,P2.4和 P2.3参加译码,基本地址范围为3000H-3FFFH。该2716有没有重叠地址?根据是什么?若 有,则写出每片2716的重叠地址范围。(仕兰微面试题目) 3、用8051设计一个带一个8*16键盘加驱动八个数码管(共阳)的原理图。(仕兰微面试题目) 4、PCI总线的含义是什么?PCI总线的主要特点是什么? (仕兰微面试题目) 5、中断的概念?简述中断的过程。(仕兰微面试题目) 6、如单片机中断几个/类型,编中断程序注意什么问题;(未知) 7、要用一个开环脉冲调速系统来控制直流电动机的转速,程序由8051完成。简单原理如下:由P3.4输出脉冲的占空比来控制转速,占空比越大,转速越快;而占空比由K7-K0八个开关来设置,直接与P1口相连(开关拨到下方时为"0",拨到上方时为"1",组成一个八位二进制数N),要求占空比为N/256。 (仕兰微面试题目) 下面程序用计数法来实现这一功能,请将空余部分添完整。 MOV P1,#0FFH LOOP1 :MOV R4,#0FFH -------- MOV R3,#00H LOOP2 :MOV A,P1 -------- SUBB A,R3 JNZ SKP1 -------- SKP1:MOV C,70H MOV P3.4,C ACALL DELAY :此延时子程序略 -------- -------- AJMP LOOP1 8、单片机上电后没有运转,首先要检查什么?(东信笔试题) 9、What is PC Chipset? (扬智电子笔试) 芯片组(Chipset)是主板的核心组成部分,按照在主板上的排列位置的不同,通常分为北桥芯片和南桥芯片。北桥芯片提供对CPU的类型和主频、内存的类型和最大容量、 ISA/PCI/AGP插槽、ECC纠错等支持。南桥芯片则提供对KBC(键盘控制器)、RTC(实时时钟控制器)、USB(通用串行总线)、Ultra DMA/33(66)EIDE数据传输方式和ACPI(高级能源管理)等的支持。其中北桥芯片起着主导性的作用,也称为主桥(Host Bridge)。 除了最通用的南北桥结构外,目前芯片组正向更高级的加速集线架构发展,Intel的8xx系列芯片组就是这类芯片组的代表,它将一些子系统如IDE接口、音效、MODEM和USB直 接接入主芯片,能够提供比PCI总线宽一倍的带宽,达到了266MB/s。 10、如果简历上还说做过cpu之类,就会问到诸如cpu如何工作,流水线之类的问题。 (未知) 11、计算机的基本组成部分及其各自的作用。(东信笔试题) 12、请画出微机接口电路中,典型的输入设备与微机接口逻辑示意图(数据接口、控制接口、所存器/缓冲器)。 (汉王笔试) 13、cache的主要部分什么的。(威盛VIA 2003.11.06 上海笔试试题) 14、同步异步传输的差异(未知) 15、串行通信与同步通信异同,特点,比较。(华为面试题) 16、RS232c高电平脉冲对应的TTL逻辑是?(负逻辑?) (华为面试题) ___________________________________________________________________________
信号与系统 1、的话音频率一般为300~3400HZ,若对其采样且使信号不失真,其最小的采样频率应为多大?若采用8KHZ的采样频率,并采用8bit的PCM编码,则存储一秒钟的信号数据量有多 大?(仕兰微面试题目) 2、什么耐奎斯特定律,怎么由模拟信号转为数字信号。(华为面试题) 3、如果模拟信号的带宽为 5khz,要用8K的采样率,怎么办? (lucent) 两路? 4、信号与系统:在时域与频域关系。(华为面试题) 5、给出时域信号,求其直流分量。(未知) 6、给出一时域信号,要求(1)写出频率分量,(2)写出其傅立叶变换级数;(3)当波形经过低通滤波器滤掉高次谐波而只保留一次谐波时,画出滤波后的输出波形。(未知) 7、sketch 连续正弦信号和连续矩形波(都有图)的傅立叶变换 。(Infineon笔试试题) 8、拉氏变换和傅立叶变换的表达式及联系。(新太硬件面题)_________________________________________________________________________ DSP、嵌入式、软件等 1、请用方框图描述一个你熟悉的实用数字信号处理系统,并做简要的分析;如果没有,也可以自己设计一个简单的数字信号处理系统,并描述其功能及用途。(仕兰微面试题 目) 2、数字滤波器的分类和结构特点。(仕兰微面试题目) 3、IIR,FIR滤波器的异同。(新太硬件面题) 4、拉氏变换与Z变换公式等类似东西,随便翻翻书把如.h(n)=-a*h(n-1)+b*δ(n) a.求h(n)的z变换;b.问该系统是否为稳定系统;c.写出FIR数字滤波器的差分方程;(未知) 5、DSP和通用处理器在结构上有什么不同,请简要画出你熟悉的一种DSP结构图。(信威 dsp软件面试题) 6、说说定点DSP和浮点DSP的定义(或者说出他们的区别)(信威dsp软件面试题) 7、说说你对循环寻址和位反序寻址的理解.(信威dsp软件面试题) 8、请写出【-8,7】的二进制补码,和二进制偏置码。用Q15表示出0.5和-0.5.(信威 dsp软件面试题) 9、DSP的结构(哈佛结构);(未知) 10、嵌入式处理器类型(如ARM),操作系统种类(Vxworks,ucos,winCE,linux),操作系 统方面偏CS方向了,在CS篇里面讲了;(未知) 11、有一个LDO芯片将用于对手机供电,需要你对他进行评估,你将如何设计你的测试项目? 12、某程序在一个嵌入式系统(200M CPU,50M SDRAM)中已经最优化了,换到零一个系统(300M CPU,50M SDRAM)中是否还需要优化? (Intel) 13、请简要描述HUFFMAN编码的基本原理及其基本的实现方法。(仕兰微面试题目) 14、说出OSI七层网络协议中的四层(任意四层)。(仕兰微面试题目) 15、A) (仕兰微面试题目) #i nclude void testf(int*p) { *p+=1; } main() { int *n,m[2]; n=m; m[0]=1; m[1]=8; testf(n); printf("Data value is %d ",*n); } ------------------------------ B) #i nclude void testf(int**p) { *p+=1; } main() {int *n,m[2]; n=m; m[0]=1; m[1]=8; testf(&n); printf(Data value is %d",*n); } 下面的结果是程序A还是程序B的? Data value is 8 那么另一段程序的结果是什么? 16、那种排序方法最快? (华为面试题) 17、写出两个排序算法,问哪个好?(威盛) 18、编一个简单的求n!的程序 。(Infineon笔试试题) 19、用一种编程语言写n!的算法。(威盛VIA 2003.11.06 上海笔试试题) 20、用C语言写一个递归算法求N!;(华为面试题) 21、给一个C的函数,关于字符串和数组,找出错误;(华为面试题) 22、防火墙是怎么实现的? (华为面试题) 23、你对哪方面编程熟悉?(华为面试题) 24、冒泡排序的原理。(新太硬件面题) 25、操作系统的功能。(新太硬件面题) 26、学过的计算机语言及开发的系统。(新太硬件面题) 27、一个农夫发现围成正方形的围栏比长方形的节省4个木桩但是面积一样.羊的数目和正方形围栏的桩子的个数一样但是小于36,问有多少羊?(威盛) 28、C语言实现统计某个cell在某.v文件调用的次数(这个题目真bt) (威盛VIA 2003.11.06 上海笔试试题) 29、用C语言写一段控制手机中马达振子的驱动程序。(威胜) 30、用perl或TCL/Tk实现一段字符串识别和比较的程序。(未知) 31、给出一个堆栈的结构,求中断后显示结果,主要是考堆栈压入返回地址存放在低端地址还是高端。(未知) 32、一些DOS命令,如显示文件,拷贝,删除。(未知) 33、设计一个类,使得该类任何形式的派生类无论怎么定义和实现,都无法产生任何对象实例。(IBM) 34、What is pre-emption? (Intel) 35、What is the state of a process if a resource is not available? (Intel) 36、三个 float a,b,c;问值(a+b)+c==(b+a)+c, (a+b)+c==(a+c)+b。(Intel) 37、把一个链表反向填空。 (lucent) 38、x^4+a*x^3+x^2+c*x+d 最少需要做几次乘法? (Dephi) ____________________________________________________________________________
主观题 1、你认为你从事研发工作有哪些特点?(仕兰微面试题目) 2、说出你的最大弱点及改进方法。(威盛VIA 2003.11.06 上海笔试试题) 3、说出你的理想。说出你想达到的目标。 题目是英文出的,要用英文回答。(威盛VIA 2003.11.06 上海笔试试题) 4、我们将研发人员分为若干研究方向,对协议和算法理解(主要应用在网络通信、图象 语音压缩方面)、电子系统方案的研究、用MCU、DSP编程实现电路功能、用ASIC设计技术设计电路(包括MCU、DSP本身)、电路功能模块设计(包括模拟电路和数字电路)、集成电路后端设计(主要是指综合及自动布局布线技术)、集成电路设计与工艺接口的研究。你希望从事哪方面的研究?(可以选择多个方向。另外,已经从事过相关研发的人员可以详细描述你的研发经历)。(仕兰微面试题目) 5、请谈谈对一个系统设计的总体思路。针对这个思路,你觉得应该具备哪些方面的知 识?(仕兰微面试题目) 6、设想你将设计完成一个电子电路方案。请简述用EDA软件(如PROTEL)进行设计(包括原理图和PCB图)到调试出样机的整个过程。在各环节应注意哪些问题?电源的稳定,电 容的选取,以及布局的大小。(汉王笔试) 共同的注意点
1.一般情况下,面试官主要根据你的简历提问,所以一定要对自己负责,把简历上的东西 搞明白; 2.个别招聘针对性特别强,就招目前他们确的方向的人,这种情况下,就要投其所好,尽量介绍其所关心的东西。 3.其实技术面试并不难,但是由于很多东西都忘掉了,才觉得有些难。所以最好在面试前把该看的书看看。 4.虽然说技术面试是实力的较量与体现,但是不可否认,由于不用面试官/公司所专领域及爱好不同,也有面试也有很大的偶然性,需要冷静对待。不能因为被拒,就否认自己或责骂公司。 5.面试时要take it easy,对越是自己钟情的公司越要这样。 各大公司电子类招聘题目精选 模拟电路 1、基尔霍夫定理的内容是什么?(仕兰微电子) 2、平板电容公式(C=εS/4πkd)。(未知) 3、最基本的如三极管曲线特性。(未知) 4、描述反馈电路的概念,列举他们的应用。(仕兰微电子) 5、负反馈种类(电压并联反馈,电流串联反馈,电压串联反馈和电流并联反馈);负反 馈的优点(降低放大器的增益灵敏度,改变输入电阻和输出电阻,改善放大器的线性和非 线性失真,有效地扩展放大器的通频带,自动调节作用)(未知) 6、放大电路的频率补偿的目的是什么,有哪些方法?(仕兰微电子) 7、频率响应,如:怎么才算是稳定的,如何改变频响曲线的几个方法。(未知) 8、给出一个查分运放,如何相位补偿,并画补偿后的波特图。(凹凸) 9、基本放大电路种类(电压放大器,电流放大器,互导放大器和互阻放大器),优缺 点,特别是广泛采用差分结构的原因。(未知) 10、给出一差分电路,告诉其输出电压Y+和Y-,求共模分量和差模分量。(未知) 11、画差放的两个输入管。(凹凸) 12、画出由运放构成加法、减法、微分、积分运算的电路原理图。并画出一个晶体管级的 运放电路。(仕兰微电子) 13、用运算放大器组成一个10倍的放大器。(未知) 14、给出一个简单电路,让你分析输出电压的特性(就是个积分电路),并求输出端某点 的 rise/fall时间。(Infineon笔试试题) 15、电阻R和电容C串联,输入电压为R和C之间的电压,输出电压分别为C上电压和R上电 压,要求制这两种电路输入电压的频谱,判断这两种电路何为高通滤波器,何为低通滤 波器。当RC<<T时,给出输入电压波形图,绘制两种电路的输出波形图。(未知) 16、有源滤波器和无源滤波器的原理及区别?(新太硬件) 17、有一时域信号S=V0sin(2pif0t)+V1cos(2pif1t)+V2sin(2pif3t+90),当其通过低通、 带通、高通滤波器后的信号表示方式。(未知) 18、选择电阻时要考虑什么?(东信笔试题) 19、在CMOS电路中,要有一个单管作为开关管精确传递模拟低电平,这个单管你会用P管 还是N管,为什么?(仕兰微电子) 20、给出多个mos管组成的电路求5个点的电压。(Infineon笔试试题) 21、电压源、电流源是集成电路中经常用到的模块,请画出你知道的线路结构,简单描述 其优缺点。(仕兰微电子) 22、画电流偏置的产生电路,并解释。(凹凸) 23、史密斯特电路,求回差电压。(华为面试题) 24、晶体振荡器,好像是给出振荡频率让你求周期(应该是单片机的,12分之一周期....) (华为面试题) 25、LC正弦波振荡器有哪几种三点式振荡电路,分别画出其原理图。(仕兰微电子) 26、VCO是什么,什么参数(压控振荡器?) (华为面试题) 27、锁相环有哪几部分组成?(仕兰微电子) 28、锁相环电路组成,振荡器(比如用D触发器如何搭)。(未知) 29、求锁相环的输出频率,给了一个锁相环的结构图。(未知) 30、如果公司做高频电子的,可能还要RF知识,调频,鉴频鉴相之类,不一一列举。(未知) 31、一电源和一段传输线相连(长度为L,传输时间为T),画出终端处波形,考虑传输线 无损耗。给出电源电压波形图,要求绘制终端波形图。(未知) 32、微波电路的匹配电阻。(未知) 33、DAC和ADC的实现各有哪些方法?(仕兰微电子) 34、A/D电路组成、工作原理。(未知) 35、实际工作所需要的一些技术知识(面试容易问到)。如电路的低功耗,稳定,高速如何做到,调运放,布版图注意的地方等等,一般会针对简历上你所写做过的东西具体问,肯定会问得很细(所以别把什么都写上,精通之类的词也别用太多了),这个东西各个人就 不一样了,不好说什么了。(未知) _______________________________________________________________________
数字电路 1、同步电路和异步电路的区别是什么?(仕兰微电子) 2、什么是同步逻辑和异步逻辑?(汉王笔试) 同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。 3、什么是"线与"逻辑,要实现它,在硬件特性上有什么具体要求?(汉王笔试) 线与逻辑是两个输出信号相连可以实现与的功能。在硬件上,要用oc门来实现,由于不用 oc门可能使灌电流过大,而烧坏逻辑门。 同时在输出端口应加一个上拉电阻。 4、什么是Setup 和Holdup时间?(汉王笔试) 5、setup和holdup时间,区别.(南山之桥) 6、解释setup time和hold time的定义和在时钟信号延迟时的变化。(未知) 7、解释setup和hold time violation,画图说明,并说明解决办法。(威盛VIA 2003.11.06 上海笔试试题) Setup/hold time 是测试芯片对输入信号和时钟信号之间的时间要求。建立时间是指触发 器的时钟信号上升沿到来以前,数据稳定不变的时间。输入信号应提前时钟上升沿(如上升沿有效)T时间到达芯片,这个T就是建立时间-Setup time.如不满足setup time,这个数据就不能被这一时钟打入触发器,只有在下一个时钟上升沿,数据才能被打入触发器。 保持时间是指触发器的时钟信号上升沿到来以后,数据稳定不变的时间。如果hold time 不够,数据同样不能被打入触发器。 建立时间(Setup Time)和保持时间(Hold time)。建立时间是指在时钟边沿前,数据信 号需要保持不变的时间。保持时间是指时钟跳变边沿后数据信号需要保持不变的时间。如果不满足建立和保持时间的话,那么DFF将不能正确地采样到数据,将会出现 metastability的情况。如果数据信号在时钟沿触发前后持续的时间均超过建立和保持时 间,那么超过量就分别被称为建立时间裕量和保持时间裕量。 8、说说对数字逻辑中的竞争和冒险的理解,并举例说明竞争和冒险怎样消除。(仕兰微 电子) 9、什么是竞争与冒险现象?怎样判断?如何消除?(汉王笔试) 在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决方法:一是添加布尔式的消去项,二是在芯片外部加电容。 10、你知道那些常用逻辑电平?TTL与COMS电平可以直接互连吗?(汉王笔试) 常用逻辑电平:12V,5V,3.3V;TTL和CMOS不可以直接互连,由于TTL是在0.3-3.6V之间,而CMOS则是有在12V的有在5V的。CMOS输出接到TTL是可以直接互连。TTL接到CMOS需要在输出端口加一上拉电阻接到5V或者12V。 11、如何解决亚稳态。(飞利浦-大唐笔试) 亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚 稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平 上。在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无 用的输出电平可以沿信号通道上的各个触发器级联式传播下去。 12、IC设计中同步复位与 异步复位的区别。(南山之桥) 13、MOORE 与 MEELEY状态机的特征。(南山之桥) 14、多时域设计中,如何处理信号跨时域。(南山之桥) 15、给了reg的setup,hold时间,求中间组合逻辑的delay范围。(飞利浦-大唐笔试) Delay < period - setup – hold 16、时钟周期为T,触发器D1的建立时间最大为T1max,最小为T1min。组合逻辑电路最大延 迟为T2max,最小为T2min。问,触发器D2的建立时间T3和保持时间应满足什么条件。(华 为) 17、给出某个一般时序电路的图,有Tsetup,Tdelay,Tck->q,还有 clock的delay,写出决 定最大时钟的因素,同时给出表达式。(威盛VIA 2003.11.06 上海笔试试题) 18、说说静态、动态时序模拟的优缺点。(威盛VIA 2003.11.06 上海笔试试题) 19、一个四级的Mux,其中第二级信号为关键信号 如何改善timing。(威盛VIA 2003.11.06 上海笔试试题) 20、给出一个门级的图,又给了各个门的传输延时,问关键路径是什么,还问给出输入, 使得输出依赖于关键路径。(未知) 21、逻辑方面数字电路的卡诺图化简,时序(同步异步差异),触发器有几种(区别,优 点),全加器等等。(未知) 22、卡诺图写出逻辑表达使。(威盛VIA 2003.11.06 上海笔试试题) 23、化简F(A,B,C,D)= m(1,3,4,5,10,11,12,13,14,15)的和。(威盛) 24、please show the CMOS inverter schmatic,layout and its cross sectionwith P- well process.Plot its transfer curve (Vout-Vin) And also explain the operation region of PMOS and NMOS for each segment of the transfer curve? (威 盛笔试题circuit design-beijing-03.11.09) 25、To design a CMOS invertor with balance rise and fall time,please define the ration of channel width of PMOS and NMOS and explain? 26、为什么一个标准的倒相器中P管的宽长比要比N管的宽长比大?(仕兰微电子) 27、用mos管搭出一个二输入与非门。(扬智电子笔试) 28、please draw the transistor level schematic of a cmos 2 input AND gate and explain which input has faster response for output rising edge.(less delay time)。(威盛笔试题circuit design-beijing-03.11.09) 29、画出NOT,NAND,NOR的符号,真值表,还有transistor level的电路。(Infineon笔 试) 30、画出CMOS的图,画出tow-to-one mux gate。(威盛VIA 2003.11.06 上海笔试试题) 31、用一个二选一mux和一个inv实现异或。(飞利浦-大唐笔试) 32、画出Y=A*B+C的cmos电路图。(科广试题) 33、用逻辑们和cmos电路实现ab+cd。(飞利浦-大唐笔试) 34、画出CMOS电路的晶体管级电路图,实现Y=A*B+C(D+E)。(仕兰微电子) 35、利用4选1实现F(x,y,z)=xz+yz’。(未知) 36、给一个表达式f=xxxx+xxxx+xxxxx+xxxx用最少数量的与非门实现(实际上就是化 简)。 37、给出一个简单的由多个NOT,NAND,NOR组成的原理图,根据输入波形画出各点波形。 (Infineon笔试) 38、为了实现逻辑(A XOR B)OR (C AND D),请选用以下逻辑中的一种,并说明为什 么?1)INV 2)AND 3)OR 4)NAND 5)NOR 6)XOR 答案:NAND(未知) 39、用与非门等设计全加法器。(华为) 40、给出两个门电路让你分析异同。(华为) 41、用简单电路实现,当A为输入时,输出B波形为…(仕兰微电子) 42、A,B,C,D,E进行投票,多数服从少数,输出是F(也就是如果A,B,C,D,E中1的个数比0 多,那么F输出为1,否则F为0),用与非门实现,输入数目没有限制。(未知) 43、用波形表示D触发器的功能。(扬智电子笔试) 44、用传输门和倒向器搭一个边沿触发器。(扬智电子笔试) 45、用逻辑们画出D触发器。(威盛VIA 2003.11.06 上海笔试试题) 46、画出DFF的结构图,用verilog实现之。(威盛) 47、画出一种CMOS的D锁存器的电路图和版图。(未知) 48、D触发器和D锁存器的区别。(新太硬件面试) 49、简述latch和filp-flop的异同。(未知) 50、LATCH和DFF的概念和区别。(未知) 51、latch与register的区别,为什么现在多用register.行为级描述中latch如何产生的。 (南山之桥) 52、用D触发器做个二分颦的电路.又问什么是状态图。(华为) 53、请画出用D触发器实现2倍分频的逻辑电路?(汉王笔试) 54、怎样用D触发器、与或非门组成二分频电路?(东信笔试) 55、How many flip-flop circuits are needed to divide by 16? (Intel) 16分频? 56、用filp-flop和logic-gate设计一个1位加法器,输入carryin和current-stage,输出 carryout和next-stage. (未知) 57、用D触发器做个4进制的计数。(华为) 58、实现N位Johnson Counter,N=5。(南山之桥) 59、用你熟悉的设计方式设计一个可预置初值的7进制循环计数器,15进制的呢?(仕兰 微电子) 60、数字电路设计当然必问Verilog/VHDL,如设计计数器。(未知) 61、BLOCKING NONBLOCKING 赋值的区别。(南山之桥) 62、写异步D触发器的verilog module。(扬智电子笔试) module dff8(clk , reset, d, q); input clk; input reset; input [7:0] d; output [7:0] q; reg [7:0] q; always @ (posedge clk or posedge reset) if(reset) q <= 0; else q <= d; endmodule 63、用D触发器实现2倍分频的Verilog描述? (汉王笔试) module divide2( clk , clk_o, reset); input clk , reset; output clk_o; wire in; reg out ; always @ ( posedge clk or posedge reset) if ( reset) out <= 0; else out <= in; assign in = ~out; assign clk_o = out; endmodule 64、可编程逻辑器件在现代电子设计中越来越重要,请问:a) 你所知道的可编程逻辑器 件有哪些? b) 试用VHDL或VERILOG、ABLE描述8位D触发器逻辑。(汉王笔试) PAL,PLD,CPLD,FPGA。 module dff8(clk , reset, d, q); input clk; input reset; input d; output q; reg q; always @ (posedge clk or posedge reset) if(reset) q <= 0; else q <= d; endmodule 65、请用HDL描述四位的全加法器、5分频电路。(仕兰微电子) 66、用VERILOG或VHDL写一段代码,实现10进制计数器。(未知) 67、用VERILOG或VHDL写一段代码,实现消除一个glitch。(未知) 68、一个状态机的题目用verilog实现(不过这个状态机画的实在比较差,很容易误解 的)。(威盛VIA 2003.11.06 上海笔试试题) 69、描述一个交通信号灯的设计。(仕兰微电子) 70、画状态机,接受1,2,5分钱的卖报机,每份报纸5分钱。(扬智电子笔试) 71、设计一个自动售货机系统,卖soda水的,只能投进三种硬币,要正确的找回钱 数。 (1)画出fsm(有限状态机);(2)用verilog编程,语法要符合fpga设计 的要求。(未知) 72、设计一个自动饮料售卖机,饮料10分钱,硬币有5分和10分两种,并考虑找零:(1) 画出fsm(有限状态机);(2)用verilog编程,语法要符合fpga设计的要求;(3)设计 工程中可使用的工具及设计大致过程。(未知) 73、画出可以检测10010串的状态图,并verilog实现之。(威盛) 74、用FSM实现101101的序列检测模块。(南山之桥) a为输入端,b为输出端,如果a连续输入为1101则b输出为1,否则为0。 例如a: 0001100110110100100110 b: 0000000000100100000000 请画出state machine;请用RTL描述其state machine。(未知) 75、用verilog/vddl检测stream中的特定字符串(分状态用状态机写)。(飞利浦-大唐 笔试) 76、用verilog/vhdl写一个fifo控制器(包括空,满,半满信号)。(飞利浦-大唐笔试) 77、现有一用户需要一种集成电路产品,要求该产品能够实现如下功能:y=lnx,其中,x 为4位二进制整数输入信号。y为二进制小数输出,要求保留两位小数。电源电压为3~5v假 设公司接到该项目后,交由你来负责该产品的设计,试讨论该产品的设计全程。(仕兰微 电子) 78、sram,falsh memory,及dram的区别?(新太硬件面试) 79、给出单管DRAM的原理图(西电版《数字电子技术基础》作者杨颂华、冯毛官205页图9 -14b),问你有什么办法提高refresh time,总共有5个问题,记不起来了。(降低温 度,增大电容存储容量)(Infineon笔试) 80、Please draw schematic of a common SRAM cell with 6 transistors,point out which nodes can store data and which node is word line control? (威盛笔试题 circuit design-beijing-03.11.09) 81、名词:sram,ssram,sdram 名词IRQ,BIOS,USB,VHDL,SDR IRQ: Interrupt ReQuest BIOS: Basic Input Output System USB: Universal Serial Bus VHDL: VHIC Hardware Description Language SDR: Single Data Rate 压控振荡器的英文缩写(VCO)。 动态随机存储器的英文缩写(DRAM)。 名词解释,无聊的外文缩写罢了,比如PCI、ECC、DDR、interrupt、pipeline、 IRQ,BIOS,USB,VHDL,VLSI VCO(压控振荡器) RAM (动态随机存储器),FIR IIR DFT(离散 傅立叶变换)或者是中文的,比如:a.量化误差 b.直方图 c.白平衡 ____________________________________________________________________________
IC设计基础(流程、工艺、版图、器件) 1、我们公司的产品是集成电路,请描述一下你对集成电路的认识,列举一些与集成电路 相关的内容(如讲清楚模拟、数字、双极型、CMOS、MCU、RISC、CISC、DSP、ASIC、FPGA 等的概念)。(仕兰微面试题目) 2、FPGA和ASIC的概念,他们的区别。(未知) 答案:FPGA是可编程ASIC。 ASIC:专用集成电路,它是面向专门用途的电路,专门为一个用户设计和制造的。根据一 个用户的特定要求,能以低研制成本,短、交货周期供货的全定制,半定制集成电路。与 门阵列等其它ASIC(Application Specific IC)相比,它们又具有设计开发周期短、设计 制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检验等优点 3、什么叫做OTP片、掩膜片,两者的区别何在?(仕兰微面试题目) 4、你知道的集成电路设计的表达方式有哪几种?(仕兰微面试题目) 5、描述你对集成电路设计流程的认识。(仕兰微面试题目) 6、简述FPGA等可编程逻辑器件设计流程。(仕兰微面试题目) 7、IC设计前端到后端的流程和eda工具。(未知) 8、从RTL synthesis到tape out之间的设计flow,并列出其中各步使用的tool.(未知) 9、Asic的design flow。(威盛VIA 2003.11.06 上海笔试试题) 10、写出asic前期设计的流程和相应的工具。(威盛) 11、集成电路前段设计流程,写出相关的工具。(扬智电子笔试) 先介绍下IC开发流程: 1.)代码输入(design input) 用vhdl或者是verilog语言来完成器件的功能描述,生成hdl代码 语言输入工具:SUMMIT VISUALHDL MENTOR RENIOR 图形输入: composer(cadence); viewlogic (viewdraw) 2.)电路仿真(circuit simulation) 将vhd代码进行先前逻辑仿真,验证功能描述是否正确 数字电路仿真工具: Verolog: CADENCE Verolig-XL SYNOPSYS VCS MENTOR Modle-sim VHDL : CADENCE NC-vhdl SYNOPSYS VSS MENTOR Modle-sim 模拟电路仿真工具: ***ANTI HSpice pspice,spectre micro microwave: eesoft : hp 3.)逻辑综合(synthesis tools) 逻辑综合工具可以将设计思想vhd代码转化成对应一定工艺手段的门级电路;将初级仿真 中所没有考虑的门沿(gates delay)反标到生成的门级网表中,返回电路仿真阶段进行再 仿真。最终仿真结果生成的网表称为物理网表。 12、请简述一下设计后端的整个流程?(仕兰微面试题目) 13、是否接触过自动布局布线?请说出一两种工具软件。自动布局布线需要哪些基本元 素?(仕兰微面试题目) 14、描述你对集成电路工艺的认识。(仕兰微面试题目) 15、列举几种集成电路典型工艺。工艺上常提到0.25,0.18指的是什么?(仕兰微面试题 目) 16、请描述一下国内的工艺现状。(仕兰微面试题目) 17、半导体工艺中,掺杂有哪几种方式?(仕兰微面试题目) 18、描述CMOS电路中闩锁效应产生的过程及最后的结果?(仕兰微面试题目) 19、解释latch-up现象和Antenna effect和其预防措施.(未知) 20、什么叫Latchup?(科广试题) 21、什么叫窄沟效应? (科广试题) 22、什么是NMOS、PMOS、CMOS?什么是增强型、耗尽型?什么是PNP、NPN?他们有什么差 别?(仕兰微面试题目) 23、硅栅COMS工艺中N阱中做的是P管还是N管,N阱的阱电位的连接有什么要求?(仕兰微 面试题目) 24、画出CMOS晶体管的CROSS-OVER图(应该是纵剖面图),给出所有可能的传输特性和转 移特性。(Infineon笔试试题) 25、以interver为例,写出N阱CMOS的process流程,并画出剖面图。(科广试题) 26、Please explain how we describe the resistance in semiconductor. Compare the resistance of a metal,poly and diffusion in tranditional CMOS process.(威 盛笔试题circuit design-beijing-03.11.09) 27、说明mos一半工作在什么区。(凹凸的题目和面试) 28、画p-bulk 的nmos截面图。(凹凸的题目和面试) 29、写schematic note(?), 越多越好。(凹凸的题目和面试) 30、寄生效应在ic设计中怎样加以克服和利用。(未知) 31、太底层的MOS管物理特性感觉一般不大会作为笔试面试题,因为全是微电子物理,公 式推导太罗索,除非面试出题的是个老学究。IC设计的话需要熟悉的软件: Cadence, Synopsys, Avant,UNIX当然也要大概会操作。 32、unix 命令cp -r, rm,uname。(扬智电子笔试) ___________________________________________________________________________
单片机、MCU、计算机原理 1、简单描述一个单片机系统的主要组成模块,并说明各模块之间的数据流流向和控制流 流向。简述单片机应用系统的设计原则。(仕兰微面试题目) 2、画出8031与2716(2K*8ROM)的连线图,要求采用三-八译码器,8031的P2.5,P2.4和 P2.3参加译码,基本地址范围为3000H-3FFFH。该2716有没有重叠地址?根据是什么?若 有,则写出每片2716的重叠地址范围。(仕兰微面试题目) 3、用8051设计一个带一个8*16键盘加驱动八个数码管(共阳)的原理图。(仕兰微面试 题目) 4、PCI总线的含义是什么?PCI总线的主要特点是什么? (仕兰微面试题目) 5、中断的概念?简述中断的过程。(仕兰微面试题目) 6、如单片机中断几个/类型,编中断程序注意什么问题;(未知) 7、要用一个开环脉冲调速系统来控制直流电动机的转速,程序由8051完成。简单原理如 下:由P3.4输出脉冲的占空比来控制转速,占空比越大,转速越快;而占空比由K7-K0八 个开关来设置,直接与P1口相连(开关拨到下方时为"0",拨到上方时为"1",组成一个八 位二进制数N),要求占空比为N/256。 (仕兰微面试题目) 下面程序用计数法来实现这一功能,请将空余部分添完整。 MOV P1,#0FFH LOOP1 :MOV R4,#0FFH -------- MOV R3,#00H LOOP2 :MOV A,P1 -------- SUBB A,R3 JNZ SKP1 -------- SKP1:MOV C,70H MOV P3.4,C ACALL DELAY :此延时子程序略 -------- -------- AJMP LOOP1 8、单片机上电后没有运转,首先要检查什么?(东信笔试题) 9、What is PC Chipset? (扬智电子笔试) 芯片组(Chipset)是主板的核心组成部分,按照在主板上的排列位置的不同,通常分为 北桥芯片和南桥芯片。北桥芯片提供对CPU的类型和主频、内存的类型和最大容量、 ISA/PCI/AGP插槽、ECC纠错等支持。南桥芯片则提供对KBC(键盘控制器)、RTC(实时时 钟控制器)、USB(通用串行总线)、Ultra DMA/33(66)EIDE数据传输方式和ACPI(高级 能源管理)等的支持。其中北桥芯片起着主导性的作用,也称为主桥(Host Bridge)。 除了最通用的南北桥结构外,目前芯片组正向更高级的加速集线架构发展,Intel的 8xx系列芯片组就是这类芯片组的代表,它将一些子系统如IDE接口、音效、MODEM和USB直 接接入主芯片,能够提供比PCI总线宽一倍的带宽,达到了266MB/s。 10、如果简历上还说做过cpu之类,就会问到诸如cpu如何工作,流水线之类的问题。 (未知) 11、计算机的基本组成部分及其各自的作用。(东信笔试题) 12、请画出微机接口电路中,典型的输入设备与微机接口逻辑示意图(数据接口、控制接 口、所存器/缓冲器)。 (汉王笔试) 13、cache的主要部分什么的。(威盛VIA 2003.11.06 上海笔试试题) 14、同步异步传输的差异(未知) 15、串行通信与同步通信异同,特点,比较。(华为面试题) 16、RS232c高电平脉冲对应的TTL逻辑是?(负逻辑?) (华为面试题) ___________________________________________________________________________
信号与系统 1、的话音频率一般为300~3400HZ,若对其采样且使信号不失真,其最小的采样频率应为 多大?若采用8KHZ的采样频率,并采用8bit的PCM编码,则存储一秒钟的信号数据量有多 大?(仕兰微面试题目) 2、什么耐奎斯特定律,怎么由模拟信号转为数字信号。(华为面试题) 3、如果模拟信号的带宽为 5khz,要用8K的采样率,怎么办? (lucent) 两路? 4、信号与系统:在时域与频域关系。(华为面试题) 5、给出时域信号,求其直流分量。(未知) 6、给出一时域信号,要求(1)写出频率分量,(2)写出其傅立叶变换级数;(3)当波 形经过低通滤波器滤掉高次谐波而只保留一次谐波时,画出滤波后的输出波形。(未知) 7、sketch 连续正弦信号和连续矩形波(都有图)的傅立叶变换 。(Infineon笔试试题) 8、拉氏变换和傅立叶变换的表达式及联系。(新太硬件面题) _________________________________________________________________________
DSP、嵌入式、软件等 1、请用方框图描述一个你熟悉的实用数字信号处理系统,并做简要的分析;如果没有, 也可以自己设计一个简单的数字信号处理系统,并描述其功能及用途。(仕兰微面试题 目) 2、数字滤波器的分类和结构特点。(仕兰微面试题目) 3、IIR,FIR滤波器的异同。(新太硬件面题) 4、拉氏变换与Z变换公式等类似东西,随便翻翻书把如.h(n)=-a*h(n-1)+b*δ(n) a.求h (n)的z变换;b.问该系统是否为稳定系统;c.写出FIR数字滤波器的差分方程;(未知) 5、DSP和通用处理器在结构上有什么不同,请简要画出你熟悉的一种DSP结构图。(信威 dsp软件面试题) 6、说说定点DSP和浮点DSP的定义(或者说出他们的区别)(信威dsp软件面试题) 7、说说你对循环寻址和位反序寻址的理解.(信威dsp软件面试题) 8、请写出【-8,7】的二进制补码,和二进制偏置码。用Q15表示出0.5和-0.5.(信威 dsp软件面试题) 9、DSP的结构(哈佛结构);(未知) 10、嵌入式处理器类型(如ARM),操作系统种类(Vxworks,ucos,winCE,linux),操作系 统方面偏CS方向了,在CS篇里面讲了;(未知) 11、有一个LDO芯片将用于对手机供电,需要你对他进行评估,你将如何设计你的测试项 目? 12、某程序在一个嵌入式系统(200M CPU,50M SDRAM)中已经最优化了,换到零一个系 统(300M CPU,50M SDRAM)中是否还需要优化? (Intel) 13、请简要描述HUFFMAN编码的基本原理及其基本的实现方法。(仕兰微面试题目) 14、说出OSI七层网络协议中的四层(任意四层)。(仕兰微面试题目) 15、A) (仕兰微面试题目) #i nclude void testf(int*p) { *p+=1; } main() { int *n,m[2]; n=m; m[0]=1; m[1]=8; testf(n); printf("Data value is %d ",*n); } ------------------------------ B) #i nclude void testf(int**p) { *p+=1; } main() {int *n,m[2]; n=m; m[0]=1; m[1]=8; testf(&n); printf(Data value is %d",*n); } 下面的结果是程序A还是程序B的? Data value is 8 那么另一段程序的结果是什么? 16、那种排序方法最快? (华为面试题) 17、写出两个排序算法,问哪个好?(威盛) 18、编一个简单的求n!的程序 。(Infineon笔试试题) 19、用一种编程语言写n!的算法。(威盛VIA 2003.11.06 上海笔试试题) 20、用C语言写一个递归算法求N!;(华为面试题) 21、给一个C的函数,关于字符串和数组,找出错误;(华为面试题) 22、防火墙是怎么实现的? (华为面试题) 23、你对哪方面编程熟悉?(华为面试题) 24、冒泡排序的原理。(新太硬件面题) 25、操作系统的功能。(新太硬件面题) 26、学过的计算机语言及开发的系统。(新太硬件面题) 27、一个农夫发现围成正方形的围栏比长方形的节省4个木桩但是面积一样.羊的数目和正 方形围栏的桩子的个数一样但是小于36,问有多少羊?(威盛) 28、C语言实现统计某个cell在某.v文件调用的次数(这个题目真bt) (威盛VIA 2003.11.06 上海笔试试题) 29、用C语言写一段控制手机中马达振子的驱动程序。(威胜) 30、用perl或TCL/Tk实现一段字符串识别和比较的程序。(未知) 31、给出一个堆栈的结构,求中断后显示结果,主要是考堆栈压入返回地址存放在低端地 址还是高端。(未知) 32、一些DOS命令,如显示文件,拷贝,删除。(未知) 33、设计一个类,使得该类任何形式的派生类无论怎么定义和实现,都无法产生任何对象 实例。(IBM) 34、What is pre-emption? (Intel) 35、What is the state of a process if a resource is not available? (Intel) 36、三个 float a,b,c;问值(a+b)+c==(b+a)+c, (a+b)+c==(a+c)+b。(Intel) 37、把一个链表反向填空。 (lucent) 38、x^4+a*x^3+x^2+c*x+d 最少需要做几次乘法? (Dephi) ____________________________________________________________________________
主观题 1、你认为你从事研发工作有哪些特点?(仕兰微面试题目) 2、说出你的最大弱点及改进方法。(威盛VIA 2003.11.06 上海笔试试题) 3、说出你的理想。说出你想达到的目标。 题目是英文出的,要用英文回答。(威盛VIA 2003.11.06 上海笔试试题) 4、我们将研发人员分为若干研究方向,对协议和算法理解(主要应用在网络通信、图象 语音压缩方面)、电子系统方案的研究、用MCU、DSP编程实现电路功能、用ASIC设计技术 设计电路(包括MCU、DSP本身)、电路功能模块设计(包括模拟电路和数字电路)、集成 电路后端设计(主要是指综合及自动布局布线技术)、集成电路设计与工艺接口的研究。
你希望从事哪方面的研究?(可以选择多个方向。另外,已经从事过相关研发的人员可以详细描述你的研发经历)。(仕兰微面试题目)
5、请谈谈对一个系统设计的总体思路。针对这个思路,你觉得应该具备哪些方面的知 识?(仕兰微面试题目)
6、设想你将设计完成一个电子电路方案。请简述用EDA软件(如PROTEL)进行设计(包括 原理图和PCB图)到调试出样机的整个过程。在各环节应注意哪些问题?电源的稳定,电 容的选取,以及布局的大小。(汉王笔试)
共同的注意点
1.一般情况下,面试官主要根据你的简历提问,所以一定要对自己负责,把简历上的东西搞明白;
2.个别招聘针对性特别强,就招目前他们确的方向的人,这种情况下,就要投其所好,尽 量介绍其所关心的东西。
3.其实技术面试并不难,但是由于很多东西都忘掉了,才觉得有些难。所以最好在面试前 把该看的书看看。
4.虽然说技术面试是实力的较量与体现,但是不可否认,由于不用面试官/公司所专领域 及爱好不同,也有面试也有很大的偶然性,需要冷静对待。不能因为被拒,就否认自己或 责骂公司。
5.面试时要take it easy,对越是自己钟情的公司越要这样
硬件工程师基础知识 作者:jialong @ 2006-05-22, 13:26 硬件工程师基础知识
目的:基于实际经验与实际项目详细理解并掌握成为合格的硬件工程师的最基本知识。
1) ;基本设计规范 2) ;CPU基本知识、架构、性能及选型指导 3) ;MOTOROLA公司的PowerPC系列基本知识、性能详解及选型指导 4) ;网络处理器(INTEL、MOTOROLA、IBM)的基本知识、架构、性能及选型 5) ;常用总线的基本知识、性能详解 6) ;各种存储器的详细性能介绍、设计要点及选型 7) ;Datacom、Telecom领域常用物理层接口芯片基本知识,性能、设计要点及选型 8) ;常用器件选型要点与精华 9) ;FPGA、CPLD、EPLD的详细性能介绍、设计要点及选型指导 10) ;VHDL和Verilog ;HDL介绍 11) ;网络基础 12) ;国内大型通信设备公司硬件研究开发流程; 二.最流行的EDA工具指导
熟练掌握并使用业界最新、最流行的专业设计工具
1) ;Innoveda公司的ViewDraw,PowerPCB,Cam350 2) ;CADENCE公司的OrCad, ;Allegro,Spectra 3) ;Altera公司的MAX+PLUS ;II 4) ;学习熟练使用VIEWDRAW、ORCAD、POWERPCB、SPECCTRA、ALLEGRO、CAM350、MAX+PLUS ;II、ISE、FOUNDATION等工具; 5) ;XILINX公司的FOUNDATION、ISE 一. ;硬件总体设计
掌握硬件总体设计所必须具备的硬件设计经验与设计思路 1) ;产品需求分析 2) ;开发可行性分析 3) ;系统方案调研 4) ;总体架构,CPU选型,总线类型 5) ;数据通信与电信领域主流CPU:M68k系列,PowerPC860,PowerPC8240,8260体系结构,性能及对比; 6) ;总体硬件结构设计及应注意的问题; 7) ;通信接口类型选择 8) ;任务分解 9) ;最小系统设计; 10) ;PCI总线知识与规范; 11) ;如何在总体设计阶段避免出现致命性错误; 12) ;如何合理地进行任务分解以达到事半功倍的效果? 13) ;项目案例:中、低端路由器等 二. ;硬件原理图设计技术 ;
目的:通过具体的项目案例,详细进行原理图设计全部经验,设计要点与精髓揭密。 1) ;电信与数据通信领域主流CPU(M68k,PowerPC860,8240,8260等)的原理设计经验与精华; 2) ;Intel公司PC主板的原理图设计精髓 3) ;网络处理器的原理设计经验与精华; 4) ;总线结构原理设计经验与精华; 5) ;内存系统原理设计经验与精华; 6) ;数据通信与电信领域通用物理层接口的原理设计经验与精华; ; 7) ;电信与数据通信设备常用的WATCHDOG的原理设计经验与精华; 8) ;电信与数据通信设备系统带电插拔原理设计经验与精华; 9) ;晶振与时钟系统原理设计经验与精华; 10) ;PCI总线的原理图设计经验与精华; 11) ;项目案例:中、低端路由器等 三.硬件PCB图设计
目的:通过具体的项目案例,进行PCB设计全部经验揭密,使你迅速成长为优秀的硬件工程师 1) ;高速CPU板PCB设计经验与精华; 2) ;普通PCB的设计要点与精华 3) ;MOTOROLA公司的PowerPC系列的PCB设计精华 4) ;Intel公司PC主板的PCB设计精华 5) ;PC主板、工控机主板、电信设备用主板的PCB设计经验精华; 6) ;国内著名通信公司PCB设计规范与工作流程; 7) ;PCB设计中生产、加工工艺的相关要求; 8) ;高速PCB设计中的传输线问题; 9) ;电信与数据通信领域主流CPU(PowerPC系列)的PCB设计经验与精华; 10) ;电信与数据通信领域通用物理层接口(百兆、千兆以太网,ATM等)的PCB设计经验与精华; 11) ;网络处理器的PCB设计经验与精华; 12) ;PCB步线的拓扑结构极其重要性; 13) ;PCI步线的PCB设计经验与精华; 14) ;SDRAM、DDR ;SDRAM(125/133MHz)的PCB设计经验与精华; 15) ;项目案例:中端路由器PCB设计 四.硬件调试
目的:以具体的项目案例,传授硬件调试、测试经验与要点 1) ;硬件调试等同于黑箱调试,如何快速分析、解决问题? 2) ;大量调试经验的传授; 3) ;如何加速硬件调试过程 4) ;如何迅速解决硬件调试问题 5) ;DATACOM终端设备的CE测试要求 五.软硬件联合调试 ;
1) ;如何判别是软件的错? 2) ;如何与软件进行联合调试? 3) ;大量的联合调试经验的传授; 目的:明确职业发展的方向与定位,真正理解大企业对人才的要求,明确个人在职业技能方面努力的方向。
1) ;职业生涯咨询与指导 2) ;如何成为优秀的硬件开发工程师并获取高薪与高职? 3) ;硬件工程师的困境与出路 4) ;优秀的硬件工程师的标准 个准电子工程师的实习经历
作者:jialong @ 2006-05-22, 13:23 昨天公司终止了我的实习合同,离开时和我们总监、部门经理、组长及带我的师傅谈了一下,昨天晚上自己也好好反省了一下,有一些感想,所以想写下来跟论坛的朋友分享一下自己一些经验感受,也希望能对即将要毕业的同学有一点点帮助了。毕竟上大学后就没写过什么东西了,有些地方写的不好,或者说表达不清楚请大家谅解。也欢迎各位大侠前来指点一下。
我是三月份开始到这家公司实习至今已有三个多月了,总的来讲收获的不少,得到的教训也不少,就是付出的太少,公司给了我一个机会,但我自己没把握住。离开公司我不后悔,只有遗憾,自己没做好。教训主要有: 一 要坦诚相待。 我在二月份和另外一家公司签了,签后了解了一下,觉得在那个公司分工太专业了,干什么就干什么,就想找一家公司去实习,在人才市场里找到现在实习的公司,在签实习合同时我给公司讲:我的三方协议书放在别的公司,我觉得我表达的够清楚了,我不知道公司是怎么理解的?反正公司同意我到公司实习。后来公司催我签三方协议书,当时因为SARS学校封校,我跟公司讲我现在不能回校(估计后来产生误会就在这里,没有沟通好,下面我也要谈谈这个问题),就说没法办,前两天学校陆续解封了,公司就托我们组长问我是什么态度,经过几个月的了解,我觉得在这家公司对我个人成长来讲是很有利的,我就说我不知道公司是什么态度,我是愿留下来的,并且我也跟她讲了我已和另一个公司签约了,组长也如实向上汇报了,公司总监就认为我不够坦诚,签时没讲清楚。我想这个原因在我,也许我当时讲的更清楚一点,就不会有今天的误会了。 二 要学会沟通 积极主动的去沟通。这点我做的不好。到公司后,由于公司想把系统由622M升级到2.5G,分配我去做宽带音频广播板,让一个师傅带我,因为是在老板子上改进,也就是重新选一个音量可调CODEC芯片,把两路立体声增加为四路,把微控制器由51换成ARM,FIFO由FPGA实现,然后把数字音频信号通过FIFO进行速率变换适配到8M HINGWAY上去。我去的时候公司正好进行规范化管理,要由单板设计方案开始做起,这对一个刚走出大学校门的学生来讲,我还是挺感激公司,给了我一个机会。然后就丛芯片选型开始,做单板设计方案,由于公司总体方案还没有确定啊,FPGA还没有选定用那家,ARM的DEMO板也没调出来,HDLC也没确定是在FPGA中实现还是用HDLC控制芯片,做到一半就走不下去了,这时我就用QuartusII 边写边仿真,中间大概有两个星期工作处于停顿状态。这时我也没向组长反映情况,报告现在碰到的困难。昨天我跟部门经理、组长谈的时候,他就提到了这个问题,就指出说我很少跟他们沟通,不了解我的情况,有困难要反映,不然就不知当时你的想法,象公司是做系统的,特别要求讲求沟通、合作。这点我做的不好。昨天我走的时候,一个搞软件的师兄就指出:我们刚毕业的学生只知道做,但不知道怎样去沟通,让你的上司看到你做了,并且做出效果来了。 三 要主动积极去做 部门经理、组长就指出我做事不够积极主动,主要体现在在中间要我跟我师傅一起调一块板子,但我师傅做了主要的,我觉得我插不上手,就没有主动去做。我觉得没做对我来讲是一个损失,少了一个学习的机会,不要因为你没经验就不去做,你不做就永远没经验去体会。 四 要有点职业精神 我想我不积极主动的原因可能是公司给我工资太少了才500块,不过我现在想起来既然我同意这个工资,那我就要认真的做下去,因为是你同意的,不管别人给你工资再少,你怎要把自己的事做好,自己问心无愧。 我觉得我实习最大的收获是:要想先做好事就要先做好人。尽管我觉得我这次实习以提前终止合同而告终,我想对我以后不管是做人还是做事都有很大帮助。 罗罗嗦嗦讲这么多,我只希望能我一样刚毕业的同学有所帮助。也希望各位大侠提出你们的宝贵意见,毕竟这是站在我的角度上所想到的,当局者迷,欢迎大家多多指教! 个人空间 :: 回复 (0) :: 静态链接网址 :: 引用 (0) 电子工程(EE)电路方面(偏底层电路级别)
作者:jialong @ 2006-05-22, 13:19 电子工程(EE)电路方面(偏底层电路级别)
1.模拟电路设计 基础知识(笔试时候容易遇到的题目) 1.最基本的如三极管曲线特性(太低极了点) 2.基本放大电路,种类,优缺点,特别是广泛采用差分结构的原因 3.反馈之类,如:负反馈的优点(带宽变大) 4.频率响应,如:怎么才算是稳定的,如何改变频响曲线的几个方法 5.锁相环电路组成,振荡器(比如用D触发器如何搭) 6.A/D电路组成,工作原理 如果公司做高频电子的,可能还要RF知识,调频,鉴频鉴相之类,不一一列举 太底层的MOS管物理特性感觉一般不大会作为笔试面试题,因为全是微电子物理,公 式推导太罗索,除非面试出题的是个老学究 ic设计的话需要熟悉的软件: Cadence, Synopsys, Advant,UNIX当然也要大概会操 作 实际工作所需要的一些技术知识(面试容易问到) 如电路的低功耗,稳定,高速如何做到,调运放,布版图注意的地方等等,一般会针 对简历上你所写做过的东西具体问,肯定会问得很细(所以别把什么都写上,精通之类的 词也别用太多了),这个东西各个人就不一样了,不好说什么了。 2.数字电路设计 当然必问Verilog/VHDL,如设计计数器 逻辑方面数字电路的卡诺图化简,时序(同步异步差异),触发器有几种(区别,优 点),全加器等等 比如:设计一个自动售货机系统,卖soda水的,只能投进三种硬币,要正确的找回钱数 1.画出fsm(有限状态机) 2.用verilog编程,语法要符合fpga设计的要求 系统方面:如果简历上还说做过cpu之类,就会问到诸如cpu如何 工作,流水线之类 的问题 3.单片机、DSP、FPGA、嵌入式方面(从没碰过,就大概知道几个名字胡扯几句,欢迎拍 砖,也欢迎牛人帮忙补充) 如单片机中断几个/类型,编中断程序注意什么问题 DSP的结构(冯.诺伊曼结构吗?) 嵌入式处理器类型(如ARM),操作系统种类(Vxworks,ucos,winCE,linux),操作系统方 面偏CS方向了,在CS篇里面讲了 4.信号系统基础 拉氏变换与Z变换公式等类似东西,随便翻翻书把 如.h(n)=-a*h(n-1)+b*δ(n) a.求h(n)的z变换 b.问该系统是否为稳定系统 c.写出F IR数字滤波器的差分方程 以往各种笔试题举例
利用4选1实现F(x,y,z)=xz+yz' 用mos管搭出一个二输入与非门。 用传输门和倒向器搭一个边沿触发器 用运算放大器组成一个10倍的放大器 微波电路的匹配电阻。 名词解释,无聊的外文缩写罢了,比如PCI、ECC、DDR、interrupt、pipeline IRQ,BIOS,USB,VHDL,VLSI VCO(压控振荡器) RAM (动态随机存储器),FIR IIR DFT(离散 傅立叶变换) 或者是中文的,比如 a量化误差 b.直方图 c.白平衡 共同的注意点
1.一般情况下,面试官主要根据你的简历提问,所以一定要对自己负责,把简历上的东 西搞明白; 2.个别招聘针对性特别强,就招目前他们确的方向的人,这种情况下,就要投其所好, 尽量介绍其所关心的东西。 3.其实技术面试并不难,但是由于很多东西都忘掉了,才觉得有些难。所以最好在面试 前把该看的书看看。 4.虽然说技术面试是实力的较量与体现,但是不可否认,由于不用面试官/公司所专领域 及爱好不同,也有面试也有很大的偶然性,需要冷静对待。不能因为被拒,就否认自己 或责骂公司。 5.面试时要take it easy,对越是自己钟情的公司越要这样。 个人空间 :: 回复 (0) :: 静态链接网址 :: 引用 (0) 献给电子类的大学生
作者:jialong @ 2006-05-22, 13:15 很久没来这里转转,今天发点牢骚吧,本人专职电源,其他系统也做,主要是硬件,软件丢光了.
五年前的10月份开始,我也是一个即将毕业的大学生(二流的),同样在为工作而到处奔波,经过一个月的奔波应聘进入联想深圳研发中心,现在在一家外企做电源FAE.结合大学及这几年的想法谈谈大学的学习. 大学--我的理解是大大的学,能精固然是好,但最重要的是能博而不要求懂,工作的时候碰到问题就会知道说我当初学过什么,应该从哪里找资料,知道从哪入手那么问题自然就简单了. 有句话说:"人知道的东西远远多于他能说出来的",因此专业课自然而然也就变的重要. 再谈细节,软件,现在的社会是金钱的社会,因此各种书籍就满天飞,软件方面也不例外(钱啊!其实我建议如果有电脑的话,可以经常上网搜,网络里面有无穷的资源),而这些书能给你的就只有概念和思想,很多人在毕业的简历上写精通C,VC,汇编等等,其实你们有几个人敢拍着胸脯说我就是行呢??书该看,经典的书更应该看,但是很重要的一点是要有实战经验. 现在的大学生月消费很高,400?500?甚者有上千,其实你们如果有心的话,可以节约一点,攒点钱去买一些demo板,这些是你实战的最好工具,从书本走向实际的第一步.而且,你把demo玩熟之后还可以把它卖给你的同学或其他等等,从开始到最后其实你花不了太多的money的,更何况知识是无价的呢,呵呵. 本人不会做软件,在吹牛见笑拉! 再谈硬件:软件由思想指导,好的思想就有可能写出好的程序,而对硬件来讲就要说到前面讲的博了!对于一个做硬件的人来讲有很多基本知识要掌握的,然后是多看,看别人的电路,见多了说不定哪天你就用的到拉. 硬件的基本知识首推模拟电子了,重中之重,模电中用的最多的是运放的应用(跟随器,比较器,放大器,滤波器,积分,微分,这些都要很熟练的),另外要熟悉(最起码要知道)一些经典电路. 模电说完就谈数电吧,其实现在的数电都很简单,很多芯片都做好了,你只要把他连接就OK了,因此我们要从另一方面入手,即对各种总线和接口要熟悉,现在常用的总线有USB,1394,PCI,PC/104,PCIE,I2C等等,不要求你理解他们的协议但是最起码应该知道有多少引脚,知道长什么模样吧;再者是接口--串口,并口,1394口,LAN,VGA,LVDS,DVI等等,要求同上. 谈到这,如果你做到了,在你找工作的时候和别人谈的话,基本上人家就不会说你眼高手低了,最起码我们有那么点货,缺少的是火货了! 还有一点,基础有了,还要有心. 有条件的话多上网,和别人交流,多看别人的问题,看别人是怎么样解决问题的,或者这种问题你知道你也可以告诉别人或者别人有不同的见解呢?!交流才会进步! 牛皮吹完了,该走拉,呵呵. 最后说一句:想做技术就要踏踏实实的学,有求实的态度! 祝你们成功! 个人空间 :: 回复 (0) :: 静态链接网址 :: 引用 (0) 开始篇
作者:jialong @ 2006-05-19, 17:39 人在生活中的每一天,都在发生着各种各样的事情,有时候还想记录一下,我想这就是最合适的地方了吧!!嗯,要记录生活中的点点滴滴
终于有了自己的BLOG了,哈哈,以后我会善心的来管理的
希望大家也能经常光顾!! 个人空间 :: 回复 (0) :: 静态链接网址 :: 引用 (0) IQ测试题
作者:jialong @ 2006-05-19, 17:34 1.有10堆苹果,每一堆10个,其中一堆每个240g,其它每堆都是250g/个,有一把称 ,请你只称一次把那一堆240的苹果找出来 .
2.三个薄壁无罩容器,分别1×1×1,2×2×2,3×3×3个单位: 请只打开一次水龙头,测出13个立方单位的水。不允许浪费水.
3.24个人要求排成6排,每排5人,如何排?
4.李开复的一道面试题:
李开复:问你一个跟计算机有点儿关系的问题。今天如果你有一千个苹果,有十个 箱子,那么现在我要把一千个苹果放进十个箱子里面,放完之后,我希望不管永华同 学(北大一学生)跟我要多少苹果,我都可以整箱整箱给他,这个问题有解吗?
解: 第一个到第九个箱子分别放1,2,4,8,16,...256。第十个箱子 放1000-511=489。 这样如要取的苹果数小于等于511则用前九个箱子的苹果来搞定,如要323=101000011即256+64 +...+2+1。如要的数M大于511且小于等于 1000,则取489+(M-489),M-489小于等于511取法和前述方法一样。
1.有10堆苹果,每一堆10个,其中一堆每个240g,其它每堆都是250g/个,有一把称 ,请你只称一次把那一堆240的苹果找出来 .
2.三个薄壁无罩容器,分别1×1×1,2×2×2,3×3×3个单位: 请只打开一次水龙头,测出13个立方单位的水。不允许浪费水.
3.24个人要求排成6排,每排5人,如何排?
4.李开复的一道面试题:
李开复:问你一个跟计算机有点儿关系的问题。今天如果你有一千个苹果,有十个 箱子,那么现在我要把一千个苹果放进十个箱子里面,放完之后,我希望不管永华同 学(北大一学生)跟我要多少苹果,我都可以整箱整箱给他,这个问题有解吗?
解: 第一个到第九个箱子分别放1,2,4,8,16,...256。第十个箱子 放1000-511=489。 这样如要取的苹果数小于等于511则用前九个箱子的苹果来搞定,如要323=101000011即256+64 +...+2+1。如要的数M大于511且小于等于 1000,则取489+(M-489),M-489小于等于511取法和前述方法一 Qt中的多线程编程2004 年 4 月 01 日 Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能。为了满足用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持。 Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能。为了满足用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持。从 2.2 版本开始,Qt 主要从下面三个方面对多线程编程提供支持:一、构造了一些基本的与平台无关的线程类;二、提交用户自定义事件的 Thread-safe 方式;三、多种线程间同步机制,如信号量,全局锁。这些都给用户提供了极大的方便。不过,在某些情况下,使用定时器机制能够比利用 Qt 本身的多线程机制更方便地实现所需要的功能,同时也避免了不安全的现象发生。本文不仅对 Qt 中的多线程支持机制进行了讨论,还着重探讨了利用定时器机制模拟多线程编程的方法。
不同的平台对 Qt 的多线程支持方式是不同的。当用户在 Windows 操作系统上安装 Qt 系统时,线程支持是编译器的一个选项,在 Qt 的 mkfiles 子目录中包括了不同种类编译器的编译文件,其中带有 -mt 后缀的文件才是支持多线程的。 而在 Unix 操作系统中,线程的支持是通过在运行 configure 脚本文件时添加 -thread 选项加入的。安装过程将创建一个独立的库,即 libqt-mt,因此要支持多线程编程时,必须与该库链接(链接选项为-lqt-mt),而不是与通常的 Qt 库(-lqt)链接。 另外,无论是何种平台,在增加线程支持时都需要定义宏 QT_THREAD_SUPPORT(即增加编译选项-DQT_THREAD_SUPPORT)。在 Windows 操作系统中,这一点通常是在 qconfig.h 文件中增加一个选项来实现的。而在 Unix 系统中通常添加在有关的 Makefile 文件中。
在 Qt 系统中与线程相关的最重要的类当然是 QThread 类,该类提供了创建一个新线程以及控制线程运行的各种方法。线程是通过 QThread::run() 重载函数开始执行的,这一点很象 Java 语言中的线程类。在 Qt 系统中,始终运行着一个GUI 主事件线程,这个主线程从窗口系统中获取事件,并将它们分发到各个组件去处理。在 QThread 类中还有一种从非主事件线程中将事件提交给一个对象的方法,也就是 QThread::postEvent()方法,该方法提供了 Qt 中的一种 Thread-safe 的事件提交过程。提交的事件被放进一个队列中,然后 GUI 主事件线程被唤醒并将此事件发给相应的对象,这个过程与一般的窗口系统事件处理过程是一样的。值得注意的是,当事件处理过程被调用时,是在主事件线程中被调用的,而不是在调用QThread::postEvent 方法的线程中被调用。比如用户可以从一个线程中迫使另一个线程重画指定区域:
然而,只有一个线程类是不够的,为编写出支持多线程的程序,还需要实现两个不同的线程对共有数据的互斥访问,因此 Qt 还提供了 QMutex 类,一个线程在访问临界数据时,需要加锁,此时其他线程是无法对该临界数据同时加锁的,直到前一个线程释放该临界数据。通过这种方式才能实现对临界数据的原子操作。 除此之外,还需要一些机制使得处于等待状态的线程在特定情况下被唤醒。QWaitCondition 类就提供了这种功能。当发生特定事件时,QWaitCondition 将唤醒等待该事件的所有线程或者唤醒任意一个被选中的线程。
在 Qt 系统中,定义了很多种类的事件,如定时器事件、鼠标移动事件、键盘事件、窗口控件事件等。通常,事件都来自底层的窗口系统,Qt 的主事件循环函数从系统的事件队列中获取这些事件,并将它们转换为 QEvent,然后传给相应的 QObjects 对象。 除此之外,为了满足用户的需求,Qt 系统还提供了一个 QCustomEvent 类,用于用户自定义事件,这些自定义事件可以利用 QThread::postEvent() 或者QApplication::postEvent() 被发给各种控件或其他 QObject 实例,而 QWidget 类的子类可以通过 QWidget::customEvent() 事件处理函数方便地接收到这些自定义的事件。需要注意的是:QCustomEvent 对象在创建时都带有一个类型标识 id 以定义事件类型,为了避免与 Qt 系统定义的事件类型冲突,该 id 值应该大于枚举类型 QEvent::Type 中给出的 "User" 值。 在下面的例子中,显示了多线程编程中如何利用用户自定义事件类。 UserEvent类是用户自定义的事件类,其事件标识为346798,显然不会与系统定义的事件类型冲突。
UserThread类是由QThread类继承而来的子类,在该类中除了定义有关的变量和线程控制函数外,最主要的是定义线程的启动函数UserThread::run(),在该函数中创建了一个用户自定义事件UserEvent,并利用QThread类的postEvent函数提交该事件给相应的接收对象。
UserWidget类是用户定义的用于接收自定义事件的QWidget类的子类,该类利用slotGo()函数创建了一个新的线程recv(UserThread类),当收到相应的自定义事件(即id为346798)时,利用customEvent函数对事件进行处理。
在这个例子中,UserWidget对象中创建了新的线程UserThread,用户可以利用这个线程实现一些周期性的处理(如接收底层发来的消息等),一旦满足特定条件就提交一个用户自定义的事件,当UserWidget对象收到该事件时,可以按需求做出相应的处理,而一般情况下,UserWidget对象可以正常地执行某些例行处理,而完全不受底层消息的影响。
为了避免Qt系统中多线程编程带来的问题,还可以使用系统中提供的定时器机制来实现类似的功能。定时器机制将并发的事件串行化,简化了对并发事件的处理,从而避免了thread-safe方面问题的出现。 在下面的例子中,同时有若干个对象需要接收底层发来的消息(可以通过Socket、FIFO等进程间通信机制),而消息是随机收到的,需要有一个GUI主线程专门负责接收消息。当收到消息时主线程初始化相应对象使之开始处理,同时返回,这样主线程就可以始终更新界面显示并接收外界发来的消息,达到同时对多个对象的控制;另一方面,各个对象在处理完消息后需要通知GUI主线程。对于这个问题,可以利用第3节中的用户自定义事件的方法,在主线程中安装一个事件过滤器,来捕捉从各个对象中发来的自定义事件,然后发出信号调用主线程中的一个槽函数。 另外,也可以利用Qt中的定时器机制实现类似的功能,而又不必担心Thread-safe问题。下面就是有关的代码部分: 在用户定义的Server类中创建和启动了定时器,并利用connect函数将定时器超时与读取设备文件数据相关联:
slotReadFile函数负责在定时器超时时,从文件中读取数据,然后重新启动定时器:
在该程序中,利用了类似轮循的方式定时对用户指定的设备文件进行读取,根据读到的数据内容将信息发送到各个相应的对象。用户可以在自己的GUI主线程中创建一个Server类,帮助实现底层的消息接收过程,而本身仍然可以处理诸如界面显示的问题。当各个对象完成处理后,通过重新启动定时器继续进行周期性读取底层设备文件的过程。当然,这种方法适合于各对象对事件的处理时间较短,而底层设备发来消息的频率又相对较慢的情况。在这种情况下,上述方法完全可以满足用户的需求,而又避免了处理一些与线程并发有关的复杂问题。 当然,利用定时器机制实现多线程编程在某些方面具有一定的局限性,有关到底如何实现多线程编程,如何编写出效率更高的代码,还有待于开发者进一步研究和探讨。 (1)Qt官方文档 http://doc.trolltech.com/3.2/index.html (2)Qt源代码:QThread, QCustomEvent,QTimer. (3)Advanced Programming in the UNIX Environment, W. Richard Stevens. Linux下C语言编程--线程操作前言:Linux下线程的创建 介绍在Linux下线程的创建和基本的使用. Linux下的线程是一个非常复杂的问题,由于我对线程的学习不时很好,我在这里只是简单的介绍线程的创建和基本的使用,关于线程的高级使用(如线程的属性,线程的互斥,线程的同步等等问题)可以参考我后面给出的资料. 现在关于线程的资料在网络上可以找到许多英文资料,后面我罗列了许多链接,对线程的高级属性感兴趣的话可以参考一下. 等到我对线程的了解比较深刻的时候,我回来完成这篇文章.如果您对线程了解的详尽我也非常高兴能够由您来完善. 先介绍什么是线程.我们编写的程序大多数可以看成是单线程的.就是程序是按照一定的顺序来执行.如果我们使用线程的话,程序就会在我们创建线成的地方分叉,变成两个"程序"在执行.粗略的看来好象和子进程差不多的,其实不然.子进程是通过拷贝父进程的地址空间来执行的.而线程是通过共享程序代码来执行的,讲的通俗一点就是线程的相同的代码会被执行几次.使用线程的好处是可以节省资源,由于线程是通过共享代码的,所以没有进程调度那么复杂. 线程的创建和使用 线程的创建是用下面的几个函数来实现的. #include int pthread_create(pthread_t *thread,pthread_attr_t *attr, void *(*start_routine)(void *),void *arg); void pthread_exit(void *retval); int pthread_join(pthread *thread,void **thread_return); pthread_create创建一个线程,thread是用来表明创建线程的ID,attr指出线程创建时候的属性,我们用NULL来表明使用缺省属性.start_routine函数指针是线程创建成功后开始执行的函数,arg是这个函数的唯一一个参数.表明传递给start_routine的参数. pthread_exit函数和exit函数类似用来退出线程.这个函数结束线程,释放函数的资源,并在最后阻塞,直到其他线程使用pthread_join函数等待它.然后将*retval的值传递给**thread_return.由于这个函数释放所以的函数资源,所以retval不能够指向函数的局部变量. pthread_join和wait调用一样用来等待指定的线程. 下面我们使用一个实例来解释一下使用方法.在实践中,我们经常要备份一些文件.下面这个程序可以实现当前目录下的所有文件备份.备份后的后缀名为bak #include #include #include #include #include #include #include #include #include #include #include #define BUFFER 512 struct copy_file { int infile; int outfile; }; void *copy(void *arg) { int infile,outfile; int bytes_read,bytes_write,*bytes_copy_p; char buffer[BUFFER],*buffer_p; struct copy_file *file=(struct copy_file *)arg; infile=file->infile; outfile=file->outfile; /* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */ if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL); bytes_read=bytes_write=0; *bytes_copy_p=0; /* 还记得怎么拷贝文件吗 */ while((bytes_read=read(infile,buffer,BUFFER))!=0) { if((bytes_read==-1)&&(errno!=EINTR))break; else if(bytes_read>0) { buffer_p=buffer; while((bytes_write=write(outfile,buffer_p,bytes_read))!=0) { if((bytes_write==-1)&&(errno!=EINTR))break; else if(bytes_write==bytes_read)break; else if(bytes_write>0) { buffer_p+=bytes_write; bytes_read-=bytes_write; } } if(bytes_write==-1)break; *bytes_copy_p+=bytes_read; } } close(infile); close(outfile); pthread_exit(bytes_copy_p); } int main(int argc,char **argv) { pthread_t *thread; struct copy_file *file; int byte_copy,*byte_copy_p,num,i,j; char filename[BUFFER]; struct dirent **namelist; struct stat filestat; /* 得到当前路径下面所有的文件(包含目录)的个数 */ if((num=scandir(".",&namelist,0,alphasort))<0) { fprintf(stderr,"Get File Num Error:%s\n\a",strerror(errno)); exit(1); } /* 给线程分配空间,其实没有必要这么多的 */ if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)|| ((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)) { fprintf(stderr,"Out Of Memory!\n\a"); exit(1); } for(i=0,j=0;i { memset(filename,'\0',BUFFER); strcpy(filename,namelist[i]->d_name); if(stat(filename,&filestat)==-1) { fprintf(stderr,"Get File Information:%s\n\a",strerror(errno)); exit(1); } /* 我们忽略目录 */ if(!S_ISREG(filestat.st_mode))continue; if((file[j].infile=open(filename,O_RDONLY))<0) { fprintf(stderr,"Open %s Error:%s\n\a",filename,strerror(errno)); continue; } strcat(filename,".bak"); if((file[j].outfile=open(filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) { fprintf(stderr,"Creat %s Error:%s\n\a",filename,strerror(errno)); continue; } /* 创建线程,进行文件拷贝 */ if(pthread_create(&thread[j],NULL,copy,(void *)&file[j])!=0) fprintf(stderr,"Create Thread[%d] Error:%s\n\a",i,strerror(errno)); j++; } byte_copy=0; for(i=0;i { /* 等待线程结束 */ if(pthread_join(thread[i],(void **)&byte_copy_p)!=0) fprintf(stderr,"Thread[%d] Join Error:%s\n\a", i,strerror(errno)); else { if(bytes_copy_p==NULL)continue; printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p); byte_copy+=*byte_copy_p; /* 释放我们在copy函数里面创建的内存 */ free(byte_copy_p); } } printf("Total Copy Bytes %d\n\a",byte_copy); free(thread); free(file); exit(0); } 线程的介绍就到这里了,关于线程的其他资料可以查看下面这写链接. Getting Started With POSIX Threads The LinuxThreads library Linux下C语言编程--进程通信、消息管理前言:Linux下的进程通信(IPC) Linux下的进程通信(IPC) 1.POSIX无名信号量 2.System V信号量 3.System V消息队列 4.System V共享内存 -------------------------------------------------------------------------------- 1。POSIX无名信号量 如果你学习过操作系统,那么肯定熟悉PV操作了.PV操作是原子操作.也就是操作是不可以中断的,在一定的时间内,只能够有一个进程的代码在CPU上面执行.在系统当中,有时候为了顺利的使用和保护共享资源,大家提出了信号的概念. 假设我们要使用一台打印机,如果在同一时刻有两个进程在向打印机输出,那么最终的结果会是什么呢.为了处理这种情况,POSIX标准提出了有名信号量和无名信号量的概念,由于Linux只实现了无名信号量,我们在这里就只是介绍无名信号量了. 信号量的使用主要是用来保护共享资源,使的资源在一个时刻只有一个进程所拥有.为此我们可以使用一个信号灯.当信号灯的值为某个值的时候,就表明此时资源不可以使用.否则就表>示可以使用. 为了提供效率,系统提供了下面几个函数 POSIX的无名信号量的函数有以下几个: #include int sem_init(sem_t *sem,int pshared,unsigned int value); int sem_destroy(sem_t *sem); int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_post(sem_t *sem); int sem_getvalue(sem_t *sem); sem_init创建一个信号灯,并初始化其值为value.pshared决定了信号量能否在几个进程间共享.由于目前Linux还没有实现进程间共享信号灯,所以这个值只能够取0. sem_destroy是用来删除信号灯的.sem_wait调用将阻塞进程,直到信号灯的值大于0.这个函数返回的时候自动的将信号灯的值的件一.sem_post和sem_wait相反,是将信号灯的内容加一同时发出信号唤醒等待的进程..sem_trywait和sem_wait相同,不过不阻塞的,当信号灯的值为0的时候返回EAGAIN,表示以后重试.sem_getvalue得到信号灯的值. 由于Linux不支持,我们没有办法用源程序解释了. 这几个函数的使用相当简单的.比如我们有一个程序要向一个系统打印机打印两页.我们首先创建一个信号灯,并使其初始值为1,表示我们有一个资源可用.然后一个进程调用sem_wait由于这个时候信号灯的值为1,所以这个函数返回,打印机开始打印了,同时信号灯的值为0 了. 如果第二个进程要打印,调用sem_wait时候,由于信号灯的值为0,资源不可用,于是被阻塞了.当第一个进程打印完成以后,调用sem_post信号灯的值为1了,这个时候系统通知第二个进程,于是第二个进程的sem_wait返回.第二个进程开始打印了. 不过我们可以使用线程来解决这个问题的.我们会在后面解释什么是线程的.编译包含上面这几个函数的程序要加上 -lrt选贤,以连接librt.so库 2。System V信号量 为了解决上面哪个问题,我们也可以使用System V信号量.很幸运的是Linux实现了System V信号量.这样我们就可以用实例来解释了. System V信号量的函数主要有下面几个. #include #include #include key_t ftok(char *pathname,char proj); int semget(key_t key,int nsems,int semflg); int semctl(int semid,int semnum,int cmd,union semun arg); int semop(int semid,struct sembuf *spos,int nspos); struct sembuf { short sem_num; /* 使用那一个信号 */ short sem_op; /* 进行什么操作 */ short sem_flg; /* 操作的标志 */ }; ftok函数是根据pathname和proj来创建一个关键字.semget创建一个信号量.成功时返回信号的ID,key是一个关键字,可以是用ftok创建的也可以是IPC_PRIVATE表明由系统选用一个关键字. nsems表明我们创建的信号个数.semflg是创建的权限标志,和我们创建一个文件的标志相同. semctl对信号量进行一系列的控制.semid是要操作的信号标志,semnum是信号的个数,cmd是操作的命令.经常用的两个值是:SETVAL(设置信号量的值)和IPC_RMID(删除信号灯).arg是一个给cmd的参数. semop是对信号进行操作的函数.semid是信号标志,spos是一个操作数组表明要进行什么操作,nspos表明数组的个数. 如果sem_op大于0,那么操作将sem_op加入到信号量的值中,并唤醒等待信号增加的进程. 如果为0,当信号量的值是0的时候,函数返回,否则阻塞直到信号量的值为0. 如果小于0,函数判断信号量的值加上这个负值.如果结果为0唤醒等待信号量为0的进程,如果小与0函数阻塞.如果大于0,那么从信号量里面减去这个值并返回. 下面我们一以一个实例来说明这几个函数的使用方法.这个程序用标准错误输出来代替我们用的打印机. #include #include #include #include #include #include #include #include #include #include #define PERMS S_IRUSR|S_IWUSR void init_semaphore_struct(struct sembuf *sem,int semnum, int semop,int semflg) { /* 初始话信号灯结构 */ sem->sem_num=semnum; sem->sem_op=semop; sem->sem_flg=semflg; } int del_semaphore(int semid) { /* 信号灯并不随程序的结束而被删除,如果我们没删除的话(将1改为0) 可以用ipcs命令查看到信号灯,用ipcrm可以删除信号灯的 */ #if 1 return semctl(semid,0,IPC_RMID); #endif } int main(int argc,char **argv) { char buffer[MAX_CANON],*c; int i,n; int semid,semop_ret,status; pid_t childpid; struct sembuf semwait,semsignal; if((argc!=2)||((n=atoi(argv[1]))<1)) { fprintf(stderr,"Usage:%s number\n\a",argv[0]); exit(1); } /* 使用IPC_PRIVATE 表示由系统选择一个关键字来创建 */ /* 创建以后信号灯的初始值为0 */ if((semid=semget(IPC_PRIVATE,1,PERMS))==-1) { fprintf(stderr,"[%d]:Acess Semaphore Error:%s\n\a", getpid(),strerror(errno)); exit(1); } /* semwait是要求资源的操作(-1) */ init_semaphore_struct(&semwait,0,-1,0); /* semsignal是释放资源的操作(+1) */ init_semaphore_struct(&semsignal,0,1,0); /* 开始的时候有一个系统资源(一个标准错误输出) */ if(semop(semid,&semsignal,1)==-1) { fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a", getpid(),strerror(errno)); if(del_semaphore(semid)==-1) fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a", getpid(),strerror(errno)); exit(1); } /* 创建一个进程链 */ for(i=0;i if(childpid=fork()) break; sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n", i,getpid(),getppid(),childpid); c=buffer; /* 这里要求资源,进入原子操作 */ while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR)); if(semop_ret==-1) { fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a", getpid(),strerror(errno)); } else { while(*c!='\0')fputc(*c++,stderr); /* 原子操作完成,赶快释放资源 */ while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR)); if(semop_ret==-1) fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a", getpid(),strerror(errno)); } /* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */ while((wait(&status)==-1)&&(errno==EINTR)); /* 信号灯只能够被删除一次的 */ if(i==1) if(del_semaphore(semid)==-1) fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a", getpid(),strerror(errno)); exit(0); } 信号灯的主要用途是保护临界资源(在一个时刻只被一个进程所拥有). 3。SystemV消息队列 为了便于进程之间通信,我们可以使用管道通信 SystemV也提供了一些函数来实现进程的通信.这就是消息队列. #include #include #include int msgget(key_t key,int msgflg); int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg); int msgrcv(int msgid,struct msgbuf *msgp,int msgsz, long msgtype,int msgflg); int msgctl(Int msgid,int cmd,struct msqid_ds *buf); struct msgbuf { long msgtype; /* 消息类型 */ ....... /* 其他数据类型 */ } msgget函数和semget一样,返回一个消息队列的标志.msgctl和semctl是对消息进行控制. msgsnd和msgrcv函数是用来进行消息通讯的.msgid是接受或者发送的消息队列标志. msgp是接受或者发送的内容.msgsz是消息的大小. 结构msgbuf包含的内容是至少有一个为msgtype.其他的成分是用户定义的.对于发送函数msgflg指出缓冲区用完时候的操作.接受函数指出无消息时候的处理.一般为0. 接收函数msgtype指出接收消息时候的操作. 如果msgtype=0,接收消息队列的第一个消息.大于0接收队列中消息类型等于这个值的第一个消息.小于0接收消息队列中小于或者等于msgtype绝对值的所有消息中的最小一个消息. 我们以一个实例来解释进程通信.下面这个程序有server和client组成.先运行服务端后运行客户端. 服务端 server.c #include #include #include #include #include #include #include #include #include #define MSG_FILE "server.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main() { struct msgtype msg; key_t key; int msgid; if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); exit(1); } if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) { fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno)); exit(1); } while(1) { msgrcv(msgid,&msg,sizeof(struct msgtype),1,0); fprintf(stderr,"Server Receive:%s\n",msg.buffer); msg.mtype=2; msgsnd(msgid,&msg,sizeof(struct msgtype),0); } exit(0); } -------------------------------------------------------------------------------- 客户端(client.c) #include #include #include #include #include #include #include #include #define MSG_FILE "server.c" #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR struct msgtype { long mtype; char buffer[BUFFER+1]; }; int main(int argc,char **argv) { struct msgtype msg; key_t key; int msgid; if(argc!=2) { fprintf(stderr,"Usage:%s string\n\a",argv[0]); exit(1); } if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno)); exit(1); } if((msgid=msgget(key,PERM))==-1) { fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno)); exit(1); } msg.mtype=1; strncpy(msg.buffer,argv[1],BUFFER); msgsnd(msgid,&msg,sizeof(struct msgtype),0); memset(&msg,'\0',sizeof(struct msgtype)); msgrcv(msgid,&msg,sizeof(struct msgtype),2,0); fprintf(stderr,"Client receive:%s\n",msg.buffer); exit(0); } 注意服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的. 4。SystemV共享内存 还有一个进程通信的方法是使用共享内存.SystemV提供了以下几个函数以实现共享内存. #include #include #include int shmget(key_t key,int size,int shmflg); void *shmat(int shmid,const void *shmaddr,int shmflg); int shmdt(const void *shmaddr); int shmctl(int shmid,int cmd,struct shmid_ds *buf); shmget和shmctl没有什么好解释的.size是共享内存的大小. shmat是用来连接共享内存的.shmdt是用来断开共享内存的.不要被共享内存词语吓倒,共享内存其实很容易实现和使用的.shmaddr,shmflg我们只要用0代替就可以了.在使用一个共享内存之前我们调用shmat得到共享内存的开始地址,使用结束以后我们使用shmdt断开这个内存. #include #include #include #include #include #include #include #include #define PERM S_IRUSR|S_IWUSR int main(int argc,char **argv) { int shmid; char *p_addr,*c_addr; if(argc!=2) { fprintf(stderr,"Usage:%s\n\a",argv[0]); exit(1); } if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) { fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno)); exit(1); } if(fork()) { p_addr=shmat(shmid,0,0); memset(p_addr,'\0',1024); strncpy(p_addr,argv[1],1024); exit(0); } else { c_addr=shmat(shmid,0,0); printf("Client get %s",c_addr); exit(0); } } 这个程序是父进程将参数写入到共享内存,然后子进程把内容读出来.最后我们要使用ipcrm释放资源的.先用ipcs找出ID然后用ipcrm shm ID删除. 后记: 进程通信(IPC)是网络程序的基础,在很多的网络程序当中会大量的使用进程通信的概念和知识.其实进程通信是一件非常复杂的事情,我在这里只是简单的介绍了一下.如果你想学习进程通信的详细知识,最好的办法是自己不断的写程序和看联机手册.现在网络上有了很多的知识可以去参考.可惜我看到的很多都是英文编写的.如果你找到了有中文的版本请尽快告诉我.谢谢! Linux下C语言编程--信号处理函数前言:这一章我们讨论一下Linux下的信号处理函数. Linux下的信号处理函数: 1.信号的产生 2.信号的处理 3.其它信号函数 -------------------------------------------------------------------------------- 一个实例 1。信号的产生 Linux下的信号可以类比于DOS下的INT或者是Windows下的事件.在有一个信号发生时候相信的信号就会发送给相应的进程.在Linux下的信号有以下几个. 我们使用 kill -l 命令可以得到以下的输出结果: 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 关于这些信号的详细解释请查看man 7 signal的输出结果. 信号事件的发生有两个来源:一个是硬件的原因(比如我们按下了键盘),一个是软件的原因(比如我们使用系统函数或者是命令发出信号). 最常用的四个发出信号的系统函数是kill, raise, alarm和setitimer函数. setitimer函数我们在计时器的使用 那一章再学习. #include #include #include int kill(pid_t pid,int sig); int raise(int sig); unisigned int alarm(unsigned int seconds); kill系统调用负责向进程发送信号sig. 如果pid是正数,那么向信号sig被发送到进程pid. 如果pid等于0,那么信号sig被发送到所以和pid进程在同一个进程组的进程 如果pid等于-1,那么信号发给所有的进程表中的进程,除了最大的哪个进程号. 如果pid由于-1,和0一样,只是发送进程组是-pid. 我们用最多的是第一个情况.还记得我们在守护进程那一节的例子吗?我们那个时候用这个函数杀死了父进程守护进程的创建 raise系统调用向自己发送一个sig信号.我们可以用上面那个函数来实现这个功能的. alarm函数和时间有点关系了,这个函数可以在seconds秒后向自己发送一个SIGALRM信号. 下面这个函数会有什么结果呢? #include main() { unsigned int i; alarm(1); for(i=0;1;i++) printf("I=%d",i); } SIGALRM的缺省操作是结束进程,所以程序在1秒之后结束,你可以看看你的最后I值为多少,来比较一下大家的系统性能差异(我的是2232). 2。信号操作 有时候我们希望进程正确的执行,而不想进程受到信号的影响,比如我们希望上面那个程序在1秒钟之后不结束.这个时候我们就要进行信号的操作了. 信号操作最常用的方法是信号屏蔽.信号屏蔽要用到下面的几个函数. #include int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set,int signo); int sigdelset(sigset_t *set,int signo); int sigismember(sigset_t *set,int signo); int sigprocmask(int how,const sigset_t *set,sigset_t *oset); sigemptyset函数初始化信号集合set,将set设置为空.sigfillset也初始化信号集合,只是将信号集合设置为所有信号的集合.sigaddset将信号signo加入到信号集合之中,sigdelset将信号从信号集合中删除.sigismember查询信号是否在信号集合之中. sigprocmask是最为关键的一个函数.在使用之前要先设置好信号集合set.这个函数的作用是将指定的信号集合set加入到进程的信号阻塞集合之中去,如果提供了oset那么当前的进程信号阻塞集合将会保存在oset里面.参数how决定函数的操作方式. SIG_BLOCK:增加一个信号集合到当前进程的阻塞集合之中. SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合. SIG_SETMASK:将当前的信号集合设置为信号阻塞集合. 以一个实例来解释使用这几个函数. #include #include #include #include int main(int argc,char **argv) { double y; sigset_t intmask; int i,repeat_factor; if(argc!=2) { fprintf(stderr,"Usage:%s repeat_factor\n\a",argv[0]); exit(1); } if((repeat_factor=atoi(argv[1]))<1)repeat_factor=10; sigemptyset(&intmask); /* 将信号集合设置为空 */ sigaddset(&intmask,SIGINT); /* 加入中断 Ctrl+C 信号*/ while(1) { /*阻塞信号,我们不希望保存原来的集合所以参数为NULL*/ sigprocmask(SIG_BLOCK,&intmask,NULL); fprintf(stderr,"SIGINT signal blocked\n"); for(i=0;i fprintf(stderr,"Blocked calculation is finished\n"); /* 取消阻塞 */ sigprocmask(SIG_UNBLOCK,&intmask,NULL); fprintf(stderr,"SIGINT signal unblocked\n"); for(i=0;i fprintf(stderr,"Unblocked calculation is finished\n"); } exit(0); } 程序在运行的时候我们要使用Ctrl+C来结束.如果我们在第一计算的时候发出SIGINT信号,由于信号已经屏蔽了,所以程序没有反映.只有到信号被取消阻塞的时候程序才会结束. 注意我们只要发出一次SIGINT信号就可以了,因为信号屏蔽只是将信号加入到信号阻塞集合之中,并没有丢弃这个信号.一旦信号屏蔽取消了,这个信号就会发生作用. 有时候我们希望对信号作出及时的反映的,比如当拥护按下Ctrl+C时,我们不想什么事情也不做,我们想告诉用户你的这个操作不好,请不要重试,而不是什么反映也没有的. 这个时候我们要用到sigaction函数. #include int sigaction(int signo,const struct sigaction *act, struct sigaction *oact); struct sigaction { void (*sa_handler)(int signo); void (*sa_sigaction)(int siginfo_t *info,void *act); sigset_t sa_mask; int sa_flags; void (*sa_restore)(void); } 这个函数和结构看起来是不是有点恐怖呢.不要被这个吓着了,其实这个函数的使用相当简单的.我们先解释一下各个参数的含义. signo很简单就是我们要处理的信号了,可以是任何的合法的信号.有两个信号不能够使用(SIGKILL和SIGSTOP). act包含我们要对这个信号进行如何处理的信息.oact更简单了就是以前对这个函数的处理信息了,主要用来保存信息的,一般用NULL就OK了. 信号结构有点复杂.不要紧我们慢慢的学习. sa_handler是一个函数型指针,这个指针指向一个函数,这个函数有一个参数.这个函数就是我们要进行的信号操作的函数. sa_sigaction,sa_restore和sa_handler差不多的,只是参数不同罢了.这两个元素我们很少使用,就不管了. sa_flags用来设置信号操作的各个情况.一般设置为0好了.sa_mask我们已经学习过了 在使用的时候我们用sa_handler指向我们的一个信号操作函数,就可以了.sa_handler有两个特殊的值:SIG_DEL和SIG_IGN.SIG_DEL是使用缺省的信号操作函数,而SIG_IGN是使用忽略该信号的操作函数. 这个函数复杂,我们使用一个实例来说明.下面这个函数可以捕捉用户的CTRL+C信号.并输出一个提示语句. #include #include #include #include #include #define PROMPT "你想终止程序吗?" char *prompt=PROMPT; void ctrl_c_op(int signo) { write(STDERR_FILENO,prompt,strlen(prompt)); } int main() { struct sigaction act; act.sa_handler=ctrl_c_op; sigemptyset(&act.sa_mask); act.sa_flags=0; if(sigaction(SIGINT,&act,NULL)<0) { fprintf(stderr,"Install Signal Action Error:%s\n\a",strerror(errno)); exit(1); } while(1); } 在上面程序的信号操作函数之中,我们使用了write函数而没有使用fprintf函数.是因为我们要考虑到下面这种情况.如果我们在信号操作的时候又有一个信号发生,那么程序该如何运行呢? 为了处理在信号处理函数运行的时候信号的发生,我们需要设置sa_mask成员. 我们将我们要屏蔽的信号添加到sa_mask结构当中去,这样这些函数在信号处理的时候就会被屏蔽掉的. 3。其它信号函数 由于信号的操作和处理比较复杂,我们再介绍几个信号操作函数. #include #include int pause(void); int sigsuspend(const sigset_t *sigmask); pause函数很简单,就是挂起进程直到一个信号发生了.而sigsuspend也是挂起进程只是在调用的时候用sigmask取代当前的信号阻塞集合. #include int sigsetjmp(sigjmp_buf env,int val); void siglongjmp(sigjmp_buf env,int val); 还记得goto函数或者是setjmp和longjmp函数吗.这两个信号跳转函数也可以实现程序的跳转让我们可以从函数之中跳转到我们需要的地方. 由于上面几个函数,我们很少遇到,所以只是说明了一下,详细情况请查看联机帮助. 4。一个实例 还记得我们在守护进程创建的哪个程序吗?守护进程在这里我们把那个程序加强一下. 下面这个程序会在也可以检查用户的邮件.不过提供了一个开关,如果用户不想程序提示有新的邮件到来,可以向程序发送SIGUSR2信号,如果想程序提供提示可以发送SIGUSR1信号. #include #include #include #include #include #include #include #include #include /* Linux 的默任个人的邮箱地址是 /var/spool/mail/ */ #define MAIL_DIR "/var/spool/mail/" /* 睡眠10秒钟 */ #define SLEEP_TIME 10 #define MAX_FILENAME 255 unsigned char notifyflag=1; long get_file_size(const char *filename) { struct stat buf; if(stat(filename,&;buf)==-1) { if(errno==ENOENT)return 0; else return -1; } return (long)buf.st_size; } void send_mail_notify(void) { fprintf(stderr,"New mail has arrived\007\n"); } void turn_on_notify(int signo) { notifyflag=1; } void turn_off_notify(int signo) { notifyflag=0; } int check_mail(const char *filename) { long old_mail_size,new_mail_size; sigset_t blockset,emptyset; sigemptyset(&;blockset); sigemptyset(&;emptyset); sigaddset(&;blockset,SIGUSR1); sigaddset(&;blockset,SIGUSR2); old_mail_size=get_file_size(filename); if(old_mail_size<0)return 1; if(old_mail_size>0) send_mail_notify(); sleep(SLEEP_TIME); while(1) { if(sigprocmask(SIG_BLOCK,&;blockset,NULL)<0) return 1; while(notifyflag==0)sigsuspend(&;emptyset); if(sigprocmask(SIG_SETMASK,&;emptyset,NULL)<0) return 1; new_mail_size=get_file_size(filename); if(new_mail_size>old_mail_size)send_mail_notify; old_mail_size=new_mail_size; sleep(SLEEP_TIME); } } int main(void) { char mailfile[MAX_FILENAME]; struct sigaction newact; struct passwd *pw; if((pw=getpwuid(getuid()))==NULL) { fprintf(stderr,"Get Login Name Error:%s\n\a",strerror(errno)); exit(1); } strcpy(mailfile,MAIL_DIR); strcat(mailfile,pw->pw_name); newact.sa_handler=turn_on_notify; newact.sa_flags=0; sigemptyset(&;newact.sa_mask); sigaddset(&;newact.sa_mask,SIGUSR1); sigaddset(&;newact.sa_mask,SIGUSR2); if(sigaction(SIGUSR1,&;newact,NULL)<0) fprintf(stderr,"Turn On Error:%s\n\a",strerror(errno)); newact.sa_handler=turn_off_notify; if(sigaction(SIGUSR1,&;newact,NULL)<0) fprintf(stderr,"Turn Off Error:%s\n\a",strerror(errno)); check_mail(mailfile); exit(0); } 信号操作是一件非常复杂的事情,比我们想象之中的复杂程度还要复杂,如果你想彻底的弄清楚信号操作的各个问题,那么除了大量的练习以外还要多看联机手册.不过如果我们只是一般的使用的话,有了上面的几个函数也就差不多了. 我们就介绍到这里了. Linux下C语言编程--时间概念 这一章我们学习Linux的时间表示和计算函数 1.时间的表示 2.时间的测量 3.计时器的使用 -------------------------------------------------------------------------------- 1。时间表示 在程序当中,我们经常要输出系统当前的时间,比如我们使用date命令的输出结果.这个时候我们可以使用下面两个函数 #include time_t time(time_t *tloc); char *ctime(const time_t *clock); time函数返回从1970年1月1日0点以来的秒数.存储在time_t结构之中.不过这个函数的返回值对于我们来说没有什么实际意义.这个时候我们使用第二个函数将秒数转化为字符串. 这个函数的返回类型是固定的:一个可能值为. Thu Dec 7 14:58:59 2000 这个字符串的长度是固定的为26 2。时间的测量 有时候我们要计算程序执行的时间.比如我们要对算法进行时间分析.这个时候可以使用下面这个函数. #include int gettimeofday(struct timeval *tv,struct timezone *tz); strut timeval { long tv_sec; /* 秒数 */ long tv_usec; /* 微秒数 */ }; gettimeofday将时间保存在结构tv之中.tz一般我们使用NULL来代替. #include <>#include < #include < void function() { unsigned int i,j; double y; for(i=0;i<1000;i++) for(j=0;j<1000;j++) y=sin((double)i); } main() { struct timeval tpstart,tpend; float timeuse; gettimeofday(&tpstart,NULL); function(); gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec; timeuse/=1000000; printf("Used Time:%f\n",timeuse); exit(0); } 这个程序输出函数的执行时间,我们可以使用这个来进行系统性能的测试,或者是函数算法的效率分析.在我机器上的一个输出结果是: Used Time:0.556070 3。计时器的使用 Linux操作系统为每一个进程提供了3个内部间隔计时器. ITIMER_REAL:减少实际时间.到时的时候发出SIGALRM信号. ITIMER_VIRTUAL:减少有效时间(进程执行的时间).产生SIGVTALRM信号. ITIMER_PROF:减少进程的有效时间和系统时间(为进程调度用的时间).这个经常和上面一个使用用来计算系统内核时间和用户时间.产生SIGPROF信号. 具体的操作函数是: #include int getitimer(int which,struct itimerval *value); int setitimer(int which,struct itimerval *newval, struct itimerval *oldval); struct itimerval { struct timeval it_interval; struct timeval it_value; } getitimer函数得到间隔计时器的时间值.保存在value中 setitimer函数设置间隔计时器的时间值为newval.并将旧值保存在oldval中. which表示使用三个计时器中的哪一个. itimerval结构中的it_value是减少的时间,当这个值为0的时候就发出相应的信号了. 然后设置为it_interval值. #include #include #include #include #include #define PROMPT "时间已经过去了两秒钟\n\a" char *prompt=PROMPT; unsigned int len; void prompt_info(int signo) { write(STDERR_FILENO,prompt,len); } void init_sigaction(void) { struct sigaction act; act.sa_handler=prompt_info; act.sa_flags=0; sigemptyset(&act.sa_mask); sigaction(SIGPROF,&act,NULL); } void init_time() { struct itimerval value; value.it_value.tv_sec=2; value.it_value.tv_usec=0; value.it_interval=value.it_value; setitimer(ITIMER_PROF,&value,NULL); } int main() { len=strlen(prompt); init_sigaction(); init_time(); while(1); exit(0); } 这个程序每执行两秒中之后会输出一个提示. Linux下C语言编程--文件的操作前言: 我们在这一节将要讨论linux下文件操作的各个函数. 1.文件的创建和读写 2.文件的各个属性 3.目录文件的操作 4.管道文件 -------------------------------------------------------------------------------- 1。文件的创建和读写 我假设你已经知道了标准级的文件操作的各个函数(fopen,fread,fwrite等等).当然如果你不清楚的话也不要着急.我们讨论的系统级的文件操作实际上是为标准级文件操作服务的. 当我们需要打开一个文件进行读写操作的时候,我们可以使用系统调用函数open.使用完成以后我们调用另外一个close函数进行关闭操作. #include #include #include #include int open(const char *pathname,int flags); int open(const char *pathname,int flags,mode_t mode); int close(int fd); open函数有两个形式.其中pathname是我们要打开的文件名(包含路径名称,缺省是认为在当前路径下面).flags可以去下面的一个值或者是几个值的组合. O_RDONLY:以只读的方式打开文件. O_WRONLY:以只写的方式打开文件. O_RDWR:以读写的方式打开文件. O_APPEND:以追加的方式打开文件. O_CREAT:创建一个文件. O_EXEC:如果使用了O_CREAT而且文件已经存在,就会发生一个错误. O_NOBLOCK:以非阻塞的方式打开一个文件. O_TRUNC:如果文件已经存在,则删除文件的内容. 前面三个标志只能使用任意的一个.如果使用了O_CREATE标志,那么我们要使用open的第二种形式.还要指定mode标志,用来表示文件的访问权限.mode可以是以下情况的组合. ----------------------------------------------------------------- S_IRUSR 用户可以读 S_IWUSR 用户可以写 S_IXUSR 用户可以执行 S_IRWXU 用户可以读写执行 ----------------------------------------------------------------- S_IRGRP 组可以读 S_IWGRP 组可以写 S_IXGRP 组可以执行 S_IRWXG 组可以读写执行 ----------------------------------------------------------------- S_IROTH 其他人可以读 S_IWOTH 其他人可以写 S_IXOTH 其他人可以执行 S_IRWXO 其他人可以读写执行 ----------------------------------------------------------------- S_ISUID 设置用户执行ID S_ISGID 设置组的执行ID ----------------------------------------------------------------- 我们也可以用数字来代表各个位的标志.Linux总共用5个数字来表示文件的各种权限. 00000.第一位表示设置用户ID.第二位表示设置组ID,第三位表示用户自己的权限位,第四位表示组的权限,最后一位表示其他人的权限. 每个数字可以取1(执行权限),2(写权限),4(读权限),0(什么也没有)或者是这几个值的和. 比如我们要创建一个用户读写执行,组没有权限,其他人读执行的文件.设置用户ID位那么我们可以使用的模式是--1(设置用户ID)0(组没有设置)7(1+2+4)0(没有权限,使用缺省)5(1+4)即10705: open("temp",O_CREAT,10705); 如果我们打开文件成功,open会返回一个文件描述符.我们以后对文件的所有操作就可以对这个文件描述符进行操作了. 当我们操作完成以后,我们要关闭文件了,只要调用close就可以了,其中fd是我们要关闭的文件描述符. 文件打开了以后,我们就要对文件进行读写了.我们可以调用函数read和write进行文件的读写. #include ssize_t read(int fd, void *buffer,size_t count); ssize_t write(int fd, const void *buffer,size_t count); fd是我们要进行读写操作的文件描述符,buffer是我们要写入文件内容或读出文件内容的内存地址.count是我们要读写的字节数. 对于普通的文件read从指定的文件(fd)中读取count字节到buffer缓冲区中(记住我们必须提供一个足够大的缓冲区),同时返回count. 如果read读到了文件的结尾或者被一个信号所中断,返回值会小于count.如果是由信号中断引起返回,而且没有返回数据,read会返回-1,且设置errno为EINTR.当程序读到了文件结尾的时候,read会返回0. write从buffer中写count字节到文件fd中,成功时返回实际所写的字节数. 下面我们学习一个实例,这个实例用来拷贝文件. #include #include #include #include #include #include #include #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int from_fd,to_fd; int bytes_read,bytes_write; char buffer[BUFFER_SIZE]; char *ptr; if(argc!=3) { fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); exit(1); } /* 打开源文件 */ if((from_fd=open(argv[1],O_RDONLY))==-1) { fprintf(stderr,"Open %s Error:%s\n",argv[1],strerror(errno)); exit(1); } /* 创建目的文件 */ if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error:%s\n",argv[2],strerror(errno)); exit(1); } /* 以下代码是一个经典的拷贝文件的代码 */ while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) { /* 一个致命的错误发生了 */ if((bytes_read==-1)&&(errno!=EINTR)) break; else if(bytes_read>0) { ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read)) { /* 一个致命错误发生了 */ if((bytes_write==-1)&&(errno!=EINTR))break; /* 写完了所有读的字节 */ else if(bytes_write==bytes_read) break; /* 只写了一部分,继续写 */ else if(bytes_write>0) { ptr+=bytes_write; bytes_read-=bytes_write; } } /* 写的时候发生的致命错误 */ if(bytes_write==-1)break; } } close(from_fd); close(to_fd); exit(0); } 2。文件的各个属性 文件具有各种各样的属性,除了我们上面所知道的文件权限以外,文件还有创建时间,大小等等属性. 有时侯我们要判断文件是否可以进行某种操作(读,写等等).这个时候我们可以使用access函数. #include int access(const char *pathname,int mode); pathname:是文件名称,mode是我们要判断的属性.可以取以下值或者是他们的组合. R_OK文件可以读,W_OK文件可以写,X_OK文件可以执行,F_OK文件存在.当我们测试成功时,函数返回0,否则如果有一个条件不符时,返回-1. 如果我们要获得文件的其他属性,我们可以使用函数stat或者fstat. #include #include int stat(const char *file_name,struct stat *buf); int fstat(int filedes,struct stat *buf); struct stat { dev_t st_dev; /* 设备 */ ino_t st_ino; /* 节点 */ mode_t st_mode; /* 模式 */ nlink_t st_nlink; /* 硬连接 */ uid_t st_uid; /* 用户ID */ gid_t st_gid; /* 组ID */ dev_t st_rdev; /* 设备类型 */ off_t st_off; /* 文件字节数 */ unsigned long st_blksize; /* 块大小 */ unsigned long st_blocks; /* 块数 */ time_t st_atime; /* 最后一次访问时间 */ time_t st_mtime; /* 最后一次修改时间 */ time_t st_ctime; /* 最后一次改变时间(指属性) */ }; stat用来判断没有打开的文件,而fstat用来判断打开的文件.我们使用最多的属性是st_mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.可以使用下面几个宏来判断. S_ISLNK(st_mode):是否是一个连接.S_ISREG是否是一个常规文件.S_ISDIR是否是一个目录S_ISCHR是否是一个字符设备.S_ISBLK是否是一个块设备S_ISFIFO是否 是一个FIFO文件.S_ISSOCK是否是一个SOCKET文件. 我们会在下面说明如何使用这几个宏的. 3。目录文件的操作 在我们编写程序的时候,有时候会要得到我们当前的工作路径。C库函数提供了getcwd来解决这个问题。 #include char *getcwd(char *buffer,size_t size); 我们提供一个size大小的buffer,getcwd会把我们当前的路径考到buffer中.如果buffer太小,函数会返回-1和一个错误号. Linux提供了大量的目录操作函数,我们学习几个比较简单和常用的函数. #include #include #include #include #include int mkdir(const char *path,mode_t mode); DIR *opendir(const char *path); struct dirent *readdir(DIR *dir); void rewinddir(DIR *dir); off_t telldir(DIR *dir); void seekdir(DIR *dir,off_t off); int closedir(DIR *dir); struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[NAME_MAX+1]; /* 文件名称 */ mkdir很容易就是我们创建一个目录,opendir打开一个目录为以后读做准备.readdir读一个打开的目录.rewinddir是用来重读目录的和我们学的rewind函数一样.closedir是关闭一个目录.telldir和seekdir类似与ftee和fseek函数. 下面我们开发一个小程序,这个程序有一个参数.如果这个参数是一个文件名,我们输出这个文件的大小和最后修改的时间,如果是一个目录我们输出这个目录下所有文件的大小和修改时间. #include #include #include #include #include #include #include static int get_file_size_time(const char *filename) { struct stat statbuf; if(stat(filename,&statbuf)==-1) { printf("Get stat on %s Error:%s\n", filename,strerror(errno)); return(-1); } if(S_ISDIR(statbuf.st_mode))return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size:%ld bytes\tmodified at %s", filename,statbuf.st_size,ctime(&statbuf.st_mtime)); return(0); } int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats; if(argc!=2) { printf("Usage:%s filename\n\a",argv[0]); exit(1); } if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1); if((dirp=opendir(argv[1]))==NULL) { printf("Open Directory %s Error:%s\n", argv[1],strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp- closedir(dirp); exit(1); } 4。管道文件 Linux提供了许多的过滤和重定向程序,比如more cat 等等.还提供了< > | <<等等重定向操作符.在这些过滤和重 定向程序当中,都用到了管道这种特殊的文件.系统调用pipe可以创建一个管道. #include int pipe(int fildes[2]); pipe调用可以创建一个管道(通信缓冲区).当调用成功时,我们可以访问文件描述符fildes[0],fildes[1].其中fildes[0]是用来读的文件描述符,而fildes[1]是用来写的文件描述符. 在实际使用中我们是通过创建一个子进程,然后一个进程写,一个进程读来使用的. 关于进程通信的详细情况请查看进程通信 #include #include #include #include #include #include #include #define BUFFER 255 int main(int argc,char **argv) { char buffer[BUFFER+1]; int fd[2]; if(argc!=2) { fprintf(stderr,"Usage:%s string\n\a",argv[0]); exit(1); } if(pipe(fd)!=0) { fprintf(stderr,"Pipe Error:%s\n\a",strerror(errno)); exit(1); } if(fork()==0) { close(fd[0]); printf("Child[%d] Write to pipe\n\a",getpid()); snprintf(buffer,BUFFER,"%s",argv[1]); write(fd[1],buffer,strlen(buffer)); printf("Child[%d] Quit\n\a",getpid()); exit(0); } else { close(fd[1]); printf("Parent[%d] Read from pipe\n\a",getpid()); memset(buffer,'\0',BUFFER+1); read(fd[0],buffer,BUFFER); printf("Parent[%d] Read:%s\n",getpid(),buffer); exit(1); } } 为了实现重定向操作,我们需要调用另外一个函数dup2. #include int dup2(int oldfd,int newfd); dup2将用oldfd文件描述符来代替newfd文件描述符,同时关闭newfd文件描述符.也就是说, 所有向newfd操作都转到oldfd上面.下面我们学习一个例子,这个例子将标准输出重定向到一个文件. #include #include #include #include #include #include #include #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int fd; char buffer[BUFFER_SIZE]; if(argc!=2) { fprintf(stderr,"Usage:%s outfilename\n\a",argv[0]); exit(1); } if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error:%s\n\a",argv[1],strerror(errno)); exit(1); } if(dup2(fd,STDOUT_FILENO)==-1) { fprintf(stderr,"Redirect Standard Out Error:%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Now,please input string"); fprintf(stderr,"(To quit use CTRL+D)\n"); while(1) { fgets(buffer,BUFFER_SIZE,stdin); if(feof(stdin))break; write(STDOUT_FILENO,buffer,strlen(buffer)); } exit(0); } 好了,文件一章我们就暂时先讨论到这里,学习好了文件的操作我们其实已经可以写出一些比较有用的程序了.我们可以编写一个实现例如dir,mkdir,cp,mv等等常用的文件操作命令了. 想不想自己写几个试一试呢? Linux下C语言编程--进程的创建前言: 这篇文章是用来介绍在Linux下和进程相关的各个概念.我们将会学到: 1.进程的概念 2.进程的身份 3.进程的创建 4.守护进程的创建 -------------------------------------------------------------------------------- 1。进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢? 在现代的操作系统里面,都有程序和进程的概念.那么什么是程序,什么是进程呢? 通俗的讲程序是一个包含可以执行代码的文件,是一个静态的文件.而进程是一个开始执行但是还没有结束的程序的实例.就是可执行文件的具体实现. 一个程序可能有许多进程,而每一个进程又可以有许多子进程.依次循环下去,而产生子孙进程. 当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作,使程序变成进程以供系统调用.在系统里面只有进程没有程序,为了区分各个不同的进程,系统给每一个进程分配了一个ID(就象我们的身份证)以便识别. 为了充分的利用资源,系统还对进程区分了不同的状态.将进程分为新建,运行,阻塞,就绪和完成五个状态. 新建表示进程正在被创建,运行是进程正在运行,阻塞是进程正在等待某一个事件发生,就绪是表示系统正在等待CPU来执行命令,而完成表示进程已经结束了系统正在回收资源. 关于进程五个状态的详细解说我们可以看《操作系统》上面有详细的解说。 2。进程的标志 上面我们知道了进程都有一个ID,那么我们怎么得到进程的ID呢?系统调用getpid可以得到进程的ID,而getppid可以得到父进程(创建调用该函数进程的进程)的ID. #include pid_t getpid(void); pid_t getppid(void); 进程是为程序服务的,而程序是为了用户服务的.系统为了找到进程的用户名,还为进程和用户建立联系.这个用户称为进程的所有者.相应的每一个用户也有一个用户ID.通过系统调用getuid可以得到进程的所有者的ID.由于进程要用到一些资源,而Linux对系统资源是进行保护的,为了获取一定资源进程还有一个有效用户ID.这个ID和系统的资源使用有关,涉及到进程的权限. 通过系统调用geteuid我们可以得到进程的有效用户ID. 和用户ID相对应进程还有一个组ID和有效组ID系统调用getgid和getegid可以分别得到组ID和有效组ID #include #include uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); git_t getegid(void); 有时候我们还会对用户的其他信息感兴趣(登录名等等),这个时候我们可以调用getpwuid来得到. struct passwd { char *pw_name; /* 登录名称 */ char *pw_passwd; /* 登录口令 */ uid_t pw_uid; /* 用户ID */ gid_t pw_gid; /* 用户组ID */ char *pw_gecos; /* 用户的真名 */ char *pw_dir; /* 用户的目录 */ char *pw_shell; /* 用户的SHELL */ }; #include #include struct passwd *getpwuid(uid_t uid); 下面我们学习一个实例来实践一下上面我们所学习的几个函数: #include #include #include #include int main(int argc,char **argv) { pid_t my_pid,parent_pid; uid_t my_uid,my_euid; gid_t my_gid,my_egid; struct passwd *my_info; my_pid=getpid(); parent_pid=getppid(); my_uid=getuid(); my_euid=geteuid(); my_gid=getgid(); my_egid=getegid(); my_info=getpwuid(my_uid); printf("Process ID:%ld\n",my_pid); printf("Parent ID:%ld\n",parent_pid); printf("User ID:%ld\n",my_uid); printf("Effective User ID:%ld\n",my_euid); printf("Group ID:%ld\n",my_gid); printf("Effective Group ID:%ld\n",my_egid): if(my_info) { printf("My Login Name:%s\n" ,my_info->pw_name); printf("My Password :%s\n" ,my_info->pw_passwd); printf("My User ID :%ld\n",my_info->pw_uid); printf("My Group ID :%ld\n",my_info->pw_gid); printf("My Real Name:%s\n" ,my_info->pw_gecos); printf("My Home Dir :%s\n", my_info->pw_dir); printf("My Work Shell:%s\n", my_info->pw_shell); } } 3。进程的创建 创建一个进程的系统调用很简单.我们只要调用fork函数就可以了. #include pid_t fork(); 当一个进程调用了fork以后,系统会创建一个子进程.这个子进程和父进程不同的地方只有他的进程ID和父进程ID,其他的都是一样.就象符进程克隆(clone)自己一样.当然创建两个一模一样的进程是没有意义的.为了区分父进程和子进程,我们必须跟踪fork的返回值. 当fork掉用失败的时候(内存不足或者是用户的最大进程数已到)fork返回-1,否则fork的返回值有重要的作用.对于父进程fork返回子进程的ID,而对于fork子进程返回0.我们就是根据这个返回值来区分父子进程的. 父进程为什么要创建子进程呢?前面我们已经说过了Linux是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源.有时进程为了早一点完成任务就创建子进程来争夺资源. 一旦子进程被创建,父子进程一起从fork处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞直到子进程完成任务.这个时候我们可以调用wait或者waitpid系统调用. #include #include pid_t wait(int *stat_loc); pid_t waitpid(pid_t pid,int *stat_loc,int options); wait系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果没有父进程没有子进程或者他的子进程已经结束了wait回立即返回.成功时(因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态.子进程调用exit,_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值. WIFEXITED:判断子进程退出值是非0 WEXITSTATUS:判断子进程的退出值(当子进程退出时非0). WIFSIGNALED:子进程由于有没有获得的信号而退出. WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义). waitpid等待指定的子进程直到子进程返回.如果pid为正值则等待指定的进程(pid).如果为0则等待任何一个组ID和调用者的组ID相同的进程.为-1时等同于wait调用.小于-1时等待任何一个组ID等于pid绝对值的进程. stat_loc和wait的意义一样. options可以决定父进程的状态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到. 父进程创建子进程后,子进程一般要执行不同的程序.为了调用系统程序,我们可以使用系统调用exec族调用.exec族调用有着5个函数. #include int execl(const char *path,const char *arg,...); int execlp(const char *file,const char *arg,...); int execle(const char *path,const char *arg,...); int execv(const char *path,char *const argv[]); int execvp(const char *file,char *const argv[]): exec族调用可以执行给定程序.关于exec族调用的详细解说可以参考系统手册(man execl). 下面我们来学习一个实例.注意编译的时候要加 -lm以便连接数学函数库. #include #include #include #include #include #include void main(void) { pid_t child; int status; printf("This will demostrate how to get child status\n"); if((child=fork())==-1) { printf("Fork Error :%s\n",strerror(errno)); exit(1); } else if(child==0) { int i; printf("I am the child:%ld\n",getpid()); for(i=0;i<1000000;i++) sin(i); i=5; printf("I exit with %d\n",i); exit(i); } while(((child=wait(&status))==-1)&(errno==EINTR)); if(child==-1) printf("Wait Error:%s\n",strerror(errno)); else if(!status) printf("Child %ld terminated normally return status is zero\n", child); else if(WIFEXITED(status)) printf("Child %ld terminated normally return status is %d\n", child,WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("Child %ld terminated due to signal %d znot caught\n", child,WTERMSIG(status)); } strerror函数会返回一个指定的错误号的错误信息的字符串. 4。守护进程的创建 如果你在DOS时代编写过程序,那么你也许知道在DOS下为了编写一个常驻内存的程序我们要编写多少代码了.相反如果在Linux下编写一个"常驻内存"的程序却是很容易的.我们只要几行代码就可以做到. 实际上由于Linux是多任务操作系统,我们就是不编写代码也可以把一个程序放到后台去执行的.我们只要在命令后面加上&符号SHELL就会把我们的程序放到后台去运行的. 这里我们"开发"一个后台检查邮件的程序.这个程序每个一个指定的时间回去检查我们的邮箱,如果发现我们有邮件了,会不断的报警(通过机箱上的小喇叭来发出声音). 后面有这个函数的加强版本加强版本 后台进程的创建思想: 首先父进程创建一个子进程.然后子进程杀死父进程(是不是很无情?). 信号处理所有的工作由子进程来处理. #include #include #include #include #include #include #include /* Linux 的默任个人的邮箱地址是 /var/spool/mail/用户的登录名 */ #define MAIL "/var/spool/mail/hoyt" /* 睡眠10秒钟 */ #define SLEEP_TIME 10 main(void) { pid_t child; if((child=fork())==-1) { printf("Fork Error:%s\n",strerror(errno)); exit(1); } else if(child>0) while(1); if(kill(getppid(),SIGTERM)==-1) { printf("Kill Parent Error:%s\n",strerror(errno)); exit(1); } { int mailfd; while(1) { if((mailfd=open(MAIL,O_RDONLY))!=-1) { fprintf(stderr,"%s","\007"); close(mailfd); } sleep(SLEEP_TIME); } } } 你可以在默认的路径下创建你的邮箱文件,然后测试一下这个程序.当然这个程序还有很多地方要改善的.我们后面会对这个小程序改善的,再看我的改善之前你可以尝试自己改善一下.比如让用户指定邮相的路径和睡眠时间等等.相信自己可以做到的.动手吧,勇敢的探险者. 好了进程一节的内容我们就先学到这里了.进程是一个非常重要的概念,许多的程序都会用子进程. Linux下C语言编程--基础知识前言: 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容: 源程序编译 Makefile的编写 程序库的链接 程序的调试 头文件和系统求助 -------------------------------------------------------------------------------- 1.源程序的编译 在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器. 假设我们有下面一个非常简单的源程序(hello.c): int main(int argc,char **argv) { printf("Hello Linux\n"); } 要编译这个程序,我们只要在命令行下执行: gcc -o hello hello.c gcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件. gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了. -o选项我们已经知道了,表示我们要求输出的可执行文件名. -c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件. -g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息. 知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明. 2.Makefile的编写 假设我们有下面这样的一个程序,源代码如下: /* main.c */ #include "mytool1.h" #include "mytool2.h" int main(int argc,char **argv) { mytool1_print("hello"); mytool2_print("hello"); } /* mytool1.h */ #ifndef _MYTOOL_1_H #define _MYTOOL_1_H void mytool1_print(char *print_str); #endif /* mytool1.c */ #include "mytool1.h" void mytool1_print(char *print_str) { printf("This is mytool1 print %s\n",print_str); } /* mytool2.h */ #ifndef _MYTOOL_2_H #define _MYTOOL_2_H void mytool2_print(char *print_str); #endif /* mytool2.c */ #include "mytool2.h" void mytool2_print(char *print_str) { printf("This is mytool2 print %s\n",print_str); } 当然由于这个程序是很短的我们可以这样来编译 gcc -c main.c gcc -c mytool1.c gcc -c mytool2.c gcc -o main main.o mytool1.o mytool2.o 这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译? 为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是: # 这是上面那个程序的Makefile文件 main:main.o mytool1.o mytool2.o gcc -o main main.o mytool1.o mytool2.o main.o:main.c mytool1.h mytool2.h gcc -c main.c mytool1.o:mytool1.c mytool1.h gcc -c mytool1.c mytool2.o:mytool2.c mytool2.h gcc -c mytool2.c 有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的. 下面我们学习Makefile是如何编写的. 在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是: target: components TAB rule 第一行表示的是依赖关系.第二行是规则. 比如说我们上面的那个Makefile文件的第二行 main:main.o mytool1.o mytool2.o 表示我们的目标(target)main的依赖对象(components)是main.o mytool1.o mytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行 gcc -o main main.o mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键 Makefile有三个非常有用的变量.分别是$@,$^,$<代表的意义分别是: $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件. 如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为: # 这是简化后的Makefile main:main.o mytool1.o mytool2.o gcc -o $@ $^ main.o:main.c mytool1.h mytool2.h gcc -c $< mytool1.o:mytool1.c mytool1.h gcc -c $< mytool2.o:mytool2.c mytool2.h gcc -c $< 经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习一个Makefile的缺省规则 .c.o: gcc -c $< 这个规则表示所有的 .o文件都是依赖与相应的.c文件的.例如mytool.o依赖于mytool.c这样Makefile还可以变为: # 这是再一次简化后的Makefile main:main.o mytool1.o mytool2.o gcc -o $@ $^ .c.o: gcc -c $< 好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile规则可以查看相应的文档. 3.程序库的链接 试着编译下面这个程序 /* temp.c */ #include int main(int argc,char **argv) { double value; printf("Value:%f\n",value); } 这个程序相当简单,但是当我们用 gcc -o temp temp.c 编译时会出现下面所示的错误. /tmp/cc33Kydu.o: In function `main': /tmp/cc33Kydu.o(.text+0xe): undefined reference to `log' collect2: ld returned 1 exit status 出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入 -lm 选项. gcc -o temp temp.c -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的 -L选项指定路径.比如说我们有一个库在 /home/hoyt/mylib下,这样我们编译的时候还要加上 -L/home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib /usr/lib /usr/local/lib 在这三个路径下面的库,我们可以不指定路径. 还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libpthread.a). 当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库. 就只好用 nm -o /lib/*.so|grep sin>~/sin 命令,然后看~/sin文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0 W sin 这样我就知道了sin在 libm-2.1.2.so库里面,我用 -lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是 -lm). 如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢! 4.程序的调试 我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了. 最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入 -g选项.关于gdb的使用可以看gdb的帮助文件.由于我没有用过这个软件,所以我也不能够说出如何使用. 不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用. 5.头文件和系统求助 有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统. 比如说我们想知道fread这个函数的确切形式,我们只要执行 man fread 系统就会输出着函数的详细解释的.和这个函数所在的头文件说明了. 如果我们要write这个函数的说明,当我们执行man write时,输出的结果却不是我们所需要的. 因为我们要的是write这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用 man 2 write. 2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数. 记住不管什么时候,man都是我们的最好助手. -------------------------------------------------------------------------------- 好了,这一章就讲这么多了,有了这些知识我们就可以进入激动人心的Linux下的C程序探险活动. 不积跬步,无以至千里! |
|
|