阅读代码习惯(转载)

hbase-server-1.1.3-API文档-中文版.zip 赠送jar包:hbase-server-1.1.3.jar; 赠送原API文档:hbase-server-1.1.3-javadoc.jar; 赠送源代码:hbase-server-1.1.3-sources.jar; 赠送Maven依赖信息文件:hbase-server-1.1.3.pom; 包含翻译后的API文档:hbase-server-1.1.3-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.hbase:hbase-server:1.1.3; 标签:server、apache、hbase、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 立即下载

 这两个习惯应该很大众化很普通,就是:

   

   1. 写代码流程分析文档

   2. 写不同场景的测试用例

   

   不过我做得比较细:

   

   

1. 写代码流程分析文档

   

   把一些难理解的、重要的代码流程写成分析文档,

   按方法调用顺序排好,通常第一次分析时不可能完全理解透的,无法理解透的可以加TODO,

   也有可能会理解错的,这都是没关系的,

   代码分析通常看一遍是不能全理解透的,需要反复几次,一步步把分析文档完善。

   

   最好是把分析文档提交到svn中,免得丢失,还可以从这些历史记录中观察自己的整个分析过程。

   

   

   如果你好几个月不关注某个开源项目的源代码了,当再次需要研究代码时,

   分析文档是非常有用的,对照代码和分析文档可以让你快速恢复到当初对代码的理解水平,

   如果没有分析文档,通常又会浪费大量时间再重做一次。

   

   以下两个例子就是我在分析HBase的HMaster和HRegionServer的启动流程时写的原始分析文档片断,

   会有一些TODO或错误或过时的地方,因为这是个在研究过程中不断完善的文档,

   并不是最终的,也没有终极文档,因为开源项目的代码一直在变动。

   

   

   

1 HMaster构造函数

  HRegionServer构造函数, HRegionServer的RPC端口默认是60020,master的RPC端口默认是60000
  HRegionServer的Jetty(InfoServer)端口默认是60030,master的Jetty(InfoServer)端口默认是60010

  1.1 获取当前运行HMaster的机器的地址
  1.2 生成HBaseServer对象用于接收RPC请求,并启动HBaseServer的相关线程
  1.3 生成ZooKeeperWatcher对象
      在构造函数中生成这些持久结点: /hbase, /hbase/unassigned, /hbase/rs, /hbase/table, /hbase/splitlog

	ZooKeeperWatcher管理下面10个结点:

	baseZNode              "/hbase"
	rootServerZNode        "/hbase/root-region-server"
	rsZNode                "/hbase/rs"
	drainingZNode          "/hbase/draining"
	masterAddressZNode     "/hbase/master"
	clusterStateZNode      "/hbase/shutdown"
	assignmentZNode        "/hbase/unassigned"
	tableZNode             "/hbase/table"
	clusterIdZNode         "/hbase/hbaseid"
	splitLogZNode          "/hbase/splitlog"
	schemaZNode            "/hbase/schema"

	这6个结点在ZooKeeperWatcher构造函数中生成
	baseZNode              "/hbase"
	rsZNode                "/hbase/rs"
	drainingZNode          "/hbase/draining"
	assignmentZNode        "/hbase/unassigned"
	tableZNode             "/hbase/table"
	splitLogZNode          "/hbase/splitlog"
	schemaZNode            "/hbase/schema"

	这4个在不同地方生成
	rootServerZNode        "/hbase/root-region-server"
	masterAddressZNode     "/hbase/master" //在HMaster中建立,并且是一个短暂结点,结点的值是HMaster的ServerName
	                                       //见org.apache.hadoop.hbase.master.ActiveMasterManager.blockUntilBecomingActiveMaster
	clusterStateZNode      "/hbase/shutdown"
	clusterIdZNode         "/hbase/hbaseid" //在HMaster.finishInitialization方法中调用ClusterId.setClusterId建立,结点值是UUID

  1.4 生成MasterMetrics对象

2 HMaster.run
  
  2.1
  生成ActiveMasterManager对象,如果此HMaster作为一个备份(backup),
  那么需要等到集群中有Active Master时才往下调用blockUntilBecomingActiveMaster,
  并且调用blockUntilBecomingActiveMaster也会阻塞,直到它变成ActiveMaster。

  与此同时,在blockUntilBecomingActiveMaster中会创建短暂结点"/hbase/master",
  此节点的值是HMaster的版本化ServerName(也就是version+ServerName),
  此结点用于协调region server的启动,只有"/hbase/master"创建好后,region server才能往下进行。
 
  2.2
  调用HMaster.finishInitialization

    2.2.1
	生成MasterFileSystem对象
	建立由hbase-site.xml的hbase.rootdir属性指定的目录(如:file:/E:/hbase-0.90.4/tmp/hbase-db/hbase)
	调用FSUtils.setVersion在hbase.rootdir目录中建立一个hbase.version文件,并写入版本号(HConstants.FILE_SYSTEM_VERSION=7)
	判断-ROOT-分区是否存在,不存在则调用MasterFileSystem.bootstrap来创新-ROOT-和.META.

	最后创建file:/E:/hbase-0.90.4/tmp/hbase-db/hbase/.oldlogs目录

	2.2.2
	如果持久结点"/hbase/hbaseid"不存在则创建它,否则不创建,同时每次master启动时都会把此节点的值设为hbase.id文件中的值

	2.2.3
	生成ExecutorService (TODO)

	2.2.4
	生成ServerManager (TODO)

	2.2.5
	initializeZKBasedSystemTrackers

	  2.2.5.1
	  生成CatalogTracker, 它包含两个ZooKeeperNodeTracker,分别是RootRegionTracker和MetaNodeTracker,
	  对应/hbase/root-region-server和/hbase/unassigned/1028785192这两个结点(1028785192是.META.的分区名)
	  如果之前从未启动过hbase,那么在start CatalogTracker时这两个结点不存在。
	  /hbase/root-region-server是一个持久结点,在RootLocationEditor中建立

	  2.2.5.2
	  生成AssignmentManager 

	  2.2.5.3
	  生成 LoadBalancer

	  2.2.5.4
	  生成 RegionServerTracker: 监控"/hbase/rs"结点

	  2.2.5.5
	  生成 DrainingServerTracker: 监控"/hbase/draining"结点

	  2.2.5.6
	  生成 ClusterStatusTracker,通过它的setClusterUp方法创建持久结点"/hbase/shutdown",结点值是当前时间,
	  如果结点已存在(master可能未正常关闭),那么此结点的值不更新。

	
	2.2.6
	生成 MasterCoprocessorHost

	2.2.7
	startServiceThreads()

	启动服务线程
	(MASTER_OPEN_REGION、MASTER_CLOSE_REGION、MASTER_SERVER_OPERATIONS、MASTER_META_SERVER_OPERATIONS、MASTER_TABLE_OPERATIONS
	这几个只是生成Executor,并未正式启动, 正式启动的有LogCleaner,和基于Jetty的InfoServer(端口号默认是60010))
	
	2.2.8
	等待RegionServer注册

	2.2.9
	splitLogAfterStartup (TODO)

	2.2.10
	assignRootAndMeta
		
		2.2.10.1
		processRegionInTransitionAndBlockUntilAssigned
		先看一下分区正在转换状态当中,如果处于转换状态当中则先处理相关的状态,并等待体处理结束后再往下进行。

		2.2.10.2
		verifyRootRegionLocation

		2.2.10.3
		getRootLocation

		2.2.10.4.A
		expireIfOnline

		2.2.10.4.B
		assignRoot

		先删掉"/hbase/root-region-server",不管它存不存在,KeeperException.NoNodeException被忽略了

		写入EventType.M_ZK_REGION_OFFLINE、当前时间戳、跟分区名(-ROOT-,,0)、master的版本化ServerName
		到/hbase/unassigned/70236052, payload为null,所以不写入

		RegionServer修改/hbase/unassigned/70236052的值,
		写入EventType.RS_ZK_REGION_OPENING、当前时间戳、跟分区名(-ROOT-,,0)、RegionServer的版本化ServerName

	
	2.2.11
	MetaMigrationRemovingHTD.updateMetaWithNewHRI

	2.2.12
	assignmentManager.joinCluster()
	把meta表中的分区读出来,然后分配到Region Server,
	meta表只有一个列族:info,存入meta的行有三列: 
	regioninfo、server、serverstartcode,
	其中regioninfo对应HRegionInfo,
	server对应ServerName的host和port(例如:myhost:60070)
	serverstartcode对应ServerName的startcode(一般是时间戳)。

		2.2.12.1
		rebuildUserRegions()
			
			2.2.12.1.1
			调用MetaReader.fullScan 从meta表中取出所有的分区,得到一个List<Result>,
			调用MetaReader.parseCatalogResult,解析每个result得到Pair<HRegionInfo, ServerName>,
			其中HRegionInfo由regioninfo列的值反序列化得来,ServerName由server、serverstartcode两列的值反序列化后组合而成。

		2.2.12.2
		processDeadServersAndRegionsInTransition

   

   

HRegionServer在reportForDuty()中向HMaster报告自己启起来后,
接着调用handleReportForDutyResponse把自己挂到zookeeper的/hbase/rs节点下(是个短暂节点),

之后HMaster就可以从/hbase/rs节点中得知有多少个HRegionServer了。


0 HRegionServer构造函数

HRegionServer构造函数, HRegionServer的RPC端口默认是60020,master的RPC端口默认是60000
HRegionServer的Jetty(InfoServer)端口默认是60030,master的Jetty(InfoServer)端口默认是60010

1 run

	1.1
	preRegistrationInitialization

	1.1.1
		initializeZooKeeper() 此方法不会创建任何节点

		. 生成ZooKeeperWatcher
		. 生成MasterAddressTracker 并等到"/hbase/master"节点有数据为止
		. 生成ClusterStatusTracker 并等到"/hbase/shutdown"节点有数据为止
		. 生成CatalogTracker 不做任何等待

	1.1.2
		initializeThreads()

		. 生成 MemStoreFlusher
		. 生成 CompactSplitThread
		. 生成 CompactionChecker
		. 生成 Leases
	
		1.1.3
	参数hbase.regionserver.nbreservationblocks默认为4,默认会预留20M(每个5M,20M = 4*5M)的内存防止OOM

	1.2
	reportForDuty

		1.2.1 getMaster()
			取出"/hbase/master"节点中的数据,构造一个master的ServerName,然后基于此生成一个HMasterRegionInterface接口的代理,
			此代理用于调用master的方法

		1.2.2 regionServerStartup

			1.2.3.1
			用rs的端口(默认是60020)、startcode(rs构造函数被调用时的时间戳),now(当前时间)这三个参数调用master的regionServerStartup.

		1.2.3 handleReportForDutyResponse
			1.2.3.2
			regionServerStartup会返回来一个MapWritable,
			这个MapWritable有三个值:
			"hbase.regionserver.hostname.seen.by.master" = master为rs重新定义的hostname(通常跟rs的InetSocketAddress.getHostName一样)
															 rs会用它重新得到serverNameFromMasterPOV
			"fs.default.name" = "file:///"
			"hbase.rootdir"	= "file:///E:/hbase/tmp"

			这三个key的值会覆盖rs原有的conf

			1.2.3.3
			查看conf中是否有"mapred.task.id",没有就自动设一个(格式: "hb_rs_"+serverNameFromMasterPOV)
			例如: hb_rs_myhost,60050,1323525314060

			1.2.3.4
			createMyEphemeralNode

			在zk中建立 短暂节点"/hbase/rs/myhost,60050,1323525314060",
			也就是把当前rs的serverNameFromMasterPOV(为null的话用rs的InetSocketAddress、port、startcode构建新的ServerName)
			放到/hbase/rs节点下,"/hbase/rs/myhost,60050,1323525314060"节点没有数据。

			1.2.3.5
			设置conf中的"fs.defaultFS"为"hbase.rootdir"的值(conf之前可能没有"fs.defaultFS"属性)

			1.2.3.6
			把"hbase.rootdir"的值保存到rootDir字段,
			生成一个只读的FSTableDescriptors

			1.2.3.7
			setupWALAndReplication

				1.2.3.7.1
				得到oldLogDir = "hbase.rootdir"的值+".oldlogs",例如: file:/E:/hbase/tmp/.oldlogs
				得到logdir		= "hbase.rootdir"的值+".logs"+serverNameFromMasterPOV,
											例如: file:/E:/hbase/tmp/.logs/myhost,60050,1323525314060

				(备注: 假设"hbase.rootdir" = "file:/E:/hbase/tmp/")

				如果logdir已存在,抛出RegionServerRunningException


				1.2.3.7.2 (TODO)
				判断是否使用Replication,默认为false,可通过"hbase.replication"参数设置

				1.2.3.7.3
				instantiateHLog
					
					1.2.3.7.3.1
					getWALActionListeners

					只有下面两个数实现了org.apache.hadoop.hbase.regionserver.wal.WALActionsListener
					org.apache.hadoop.hbase.regionserver.LogRoller
					org.apache.hadoop.hbase.replication.regionserver.Replication

					LogRoller会加入WALActionsListener列表中
					"hbase.replication"参数的值是true时,Replication也被加入


					1.2.3.7.3.2 (TODO)
					生成一个新的HLog
					在他的构造函数中会建立oldLogDir和logdir两个目录,
					prefix字段的值是serverNameFromMasterPOV经过URLEncoder.encode(prefix, "UTF8")后的值,
					然后在logdir目录中生成一个新的日志文件,
					日志文件名是prefix+当前时间戳,比如: myhost%2C60050%2C1323525314060.1323527965276

			1.2.3.8
			生成RegionServerMetrics

			1.2.3.9
			startServiceThreads

			RS_OPEN_REGION RS_OPEN_ROOT RS_OPEN_META
			RS_CLOSE_REGION RS_CLOSE_ROOT RS_CLOSE_META
			这6个并未正真启动,只是生成Executor。

			启动的线程有:
			LogRoller
			MemStoreFlusher
			CompactionChecker
			Leases
			Jetty InfoServer (可通过"/rs-status"和"/dump"这两个url来访问rs的相关信息)
			Replication(待确定 TODO)
			SplitLogWorker

		1.2.4 周期性(msgInterval默认3妙)调用doMetrics,tryRegionServerReport

			1.2.4.1
			isHealthy健康检查,只要Leases、MemStoreFlusher、LogRoller、CompactionChecker有一个线程退出,rs就停止
			
			1.2.4.2
			doMetrics

			1.2.4.3
			tryRegionServerReport
			向master汇报rs的负载HServerLoad

   

   

2. 写不同场景的测试用例

   

   例子一般是验证某个方法中的代码的各种分枝,

   还有些是验证几个类之间的调用关系的,

   这种测试用例有可能很多,最好还是自己写一写,

   去看开源项目自带的一般也没那么详细而且你还要了解它的测试代码,

   还不如自己写来得快,通常这些测试例子不是一次性完成的,

   一般是分析方档写到哪,你就可以写些例子来测试一下。

   

   下面这个例子就是我在分析H2数据库在解析Insert SQL语法时写的例子,

   几乎含盖了所有的场景,同时顺便测试记录是怎么存入表中的,会触发哪些触发器。

   (在Eclipse中可以按CTRL+/来注释掉一些已经测过的,例子通常是按开源项目的代码运行流程的先后顺序来写的)

   

package my.test.sql;

import java.sql.Connection;
import java.sql.SQLException;

import my.test.TestBase;

//找断点条件
//table.getName().equalsIgnoreCase("InsertTest");
public class InsertTest extends TestBase {
	public static void main(String[] args) throws Exception {
		new InsertTest().start();
	}

	public static class MyInsertTrigger implements org.h2.api.Trigger {

		@Override
		public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before, int type)
				throws SQLException {
			System.out.println("schemaName=" + schemaName + " tableName=" + tableName);

		}

		@Override
		public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException {
			System.out.println("oldRow=" + oldRow + " newRow=" + newRow);
		}

		@Override
		public void close() throws SQLException {
			System.out.println("my.test.sql.InsertTest.MyInsertTrigger.close()");
		}

		@Override
		public void remove() throws SQLException {
			System.out.println("my.test.sql.InsertTest.MyInsertTrigger.remove()");
		}

	}

	//测试org.h2.command.Parser.parseInsert()和org.h2.command.dml.Insert
	@Override
	public void startInternal() throws Exception {
		conn.setAutoCommit(false);

		stmt.executeUpdate("DROP TABLE IF EXISTS InsertTest");
		//stmt.executeUpdate("CREATE TABLE IF NOT EXISTS InsertTest(id int not null, name varchar(500) not null)");
		stmt.executeUpdate("CREATE TABLE IF NOT EXISTS InsertTest(id int, name varchar(500))");

		stmt.executeUpdate("CREATE TRIGGER IF NOT EXISTS TriggerInsertTest BEFORE INSERT ON InsertTest "
				//+ "FOR EACH ROW CALL \\"my.test.sql.InsertTest$MyInsertTrigger\\"");
				+ "CALL \\"my.test.sql.InsertTest$MyInsertTrigger\\"");

		stmt.executeUpdate("DROP TABLE IF EXISTS tmpSelectTest");
		stmt.executeUpdate("CREATE TABLE IF NOT EXISTS tmpSelectTest(id int, name varchar(500))");
		stmt.executeUpdate("INSERT INTO tmpSelectTest VALUES(DEFAULT, DEFAULT),(10, \'a\'),(20, \'b\')");

		//从另一表查数据,然后插入此表
		stmt.executeUpdate("INSERT INTO InsertTest(SELECT * FROM tmpSelectTest)");
		stmt.executeUpdate("INSERT INTO InsertTest(FROM tmpSelectTest SELECT *)"); //FROM开头先也是支持的

		//DEFAULT VALUES这种语法不适合用于not null字段
		stmt.executeUpdate("INSERT INTO InsertTest DIRECT SORTED DEFAULT VALUES");
		//DEFAULT VALUES这种语法不能在表名之后又指定字段列表
		//stmt.executeUpdate("INSERT INTO InsertTest(name) DIRECT SORTED DEFAULT VALUES");

		//这种语法可查入多条记录
		//null null
		//10 a
		//20 b
		//stmt.executeUpdate("INSERT INTO InsertTest VALUES(DEFAULT, DEFAULT),(10, \'a\'),(20, \'b\')");

		//SET语法不能在表名之后又指定字段列表
		//stmt.executeUpdate("INSERT INTO InsertTest(name) SET name=\'xyz\')");
		//虽然在语法上可以重复相同的字段,本意是想插入多条记录,但是实际上只有一条,就是最后一个id和name
		//stmt.executeUpdate("INSERT INTO InsertTest SET id=DEFAULT, name=DEFAULT, id=10, name=\'a\', id=20, name=\'b\'");

		//列必须一样多,否则:
		//Exception in thread "main" org.h2.jdbc.JdbcSQLException: Column count does not match; SQL statement:
		//INSERT INTO InsertTest(name) (SELECT * FROM tmpSelectTest) [21002-169]
		//stmt.executeUpdate("INSERT INTO InsertTest(name) (SELECT * FROM tmpSelectTest)");
		//stmt.executeUpdate("INSERT INTO InsertTest(name) (FROM tmpSelectTest SELECT *)"); //FROM开头先也是支持的

		stmt.executeUpdate("INSERT INTO InsertTest(name) (SELECT name FROM tmpSelectTest)");
		stmt.executeUpdate("INSERT INTO InsertTest(name) (FROM tmpSelectTest SELECT name)"); //FROM开头先也是支持的

		//SELECT语句不带括号也是允许的
		stmt.executeUpdate("INSERT INTO InsertTest(name) SELECT name FROM tmpSelectTest");
		stmt.executeUpdate("INSERT INTO InsertTest(name) FROM tmpSelectTest SELECT name"); //FROM开头先也是支持的

		stmt.executeUpdate("INSERT INTO InsertTest(name) DIRECT FROM tmpSelectTest SELECT name"); //FROM开头先也是支持的

		ps = conn.prepareStatement("INSERT INTO InsertTest(id, name) VALUES(?, ?)");
		ps.setInt(1, 30);
		ps.setString(2, "c");
		ps.executeUpdate();

		stmt.executeQuery("EXPLAIN INSERT INTO InsertTest(name) DIRECT FROM tmpSelectTest SELECT name");

		sql = "select id,name from InsertTest";
		rs = stmt.executeQuery(sql);
		while (rs.next()) {
			System.out.println(rs.getString(1) + " " + rs.getString(2));
		}

		conn.commit();
		//conn.rollback();
	}
}
专为AI打造的浏览器:内存占用仅为Chrome的1/9、比Chrome快11倍(Docker部署教程,支持飞牛nas等服务器部署) 🚀 专为AI打造的无头浏览器来了! 用Zig从零构建,内存仅Chrome的1/9,速度快11倍,原生CDP协议支持Docker部署,适合爬虫、自动化测试和AI代理应用。✨ 阅读详情

相关推荐

(04730)半导体器件之基本放大器工作原理(一)

放大器是构成各种电子线路的基本单元电路。所谓“放大”,就是将输入的微弱信号(微弱变化的电压或电流等)去控制直流电源提供的能量,并使输出按照输入的小信号变化规律而变化的过程。所以放大器的本质是能量转换器。本节重点学习基本放大电路的工作原理和基本分析方法及主要性能指标。

黄先生的博客 3006

8. Hadoop Hbase服务

hadoop hbase操作

. 436

STM32串口接收避坑指南:为什么你的USART_IT_IDLE中断不触发?附完整调试流程

本文深入解析STM32串口接收中断机制,特别是USART_IT_IDLE中断不触发的常见原因及解决方案。通过详细分析中断标志清除顺序、波特率配置、硬件连接等关键因素,并提供完整的调试流程和代码示例,帮助开发者快速定位并解决串口通信问题。

weixin_42519985的博客 347

HBase RegionServer挂掉导致集群不可用问题

生产中HBase RegionServer挂掉一个,整个集群却不可用了,排查下问题原因

寂寞的博客 6375

Drupal远程代码执行漏洞(CVE-2018-7600)实战复现:从检测到写入WebShell的全过程

本文详细解析了Drupal远程代码执行漏洞(CVE-2018-7600)的实战复现过程,从环境搭建、漏洞检测到WebShell写入的全流程。该高危漏洞影响Drupal 6.x至8.x版本,允许攻击者未经授权执行任意代码。文章提供了多种POC构造方法和高级利用技巧,帮助安全研究人员深入理解漏洞原理并掌握验证技术。

weixin_29322553的博客 275

oh-my-zsh详细安装与主题插件配置

使用Linux的小伙伴都知道默认shell是bash,但是对于喜欢折腾,喜欢酷炫的我们bash怎能够用。zsh的作为一种shell,功能更强大,但是配置复杂。后来,有大佬创建了一个名为oh-my-zsh的开源项目,使用方便,功能强大。 下面就去oh-my-zsh的配置。 ①安装zsh 想要安装oh-my-zsh,首先得安装zsh,输入命令 sudo apt-get install zsh 界面如下 ②查看是否安装成功 输入命令 zsh --version 可以查看安装zsh的版本..

惜洛-Jankin的博客 2万+

zookeeper --Refusing session request for client

启动zookeeper报错解决方法 一、启动zookeeper时,后台一直报错,错误描述 2014-03-18 09:03:50,703 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:12 181:NIOServerCnxnFactory@197] - Accepted socket connection from / 1

实践助梦想成长 4万+

Win10内网离线安装NET3.5,绝对成功,保姆级

今天工作安装工具软件套装3.5组件!也在csdn上找了很多方法躺了很多坑,我总结如下! 其实就一条,什么版本的win10装什么版本的net3.5 我的电脑是1909版本,用2004H2的镜像是没有用的,dism组件报错8024402C 所以我下载1909镜像挂在虚拟光驱 ,管理员模式下powershell dism.exe /online /enable-feature /featurename:NetFX3 /Source:E:\sources\sxs dism.exe /online /en..

唉呀妈呀脑瓜疼 6万+

HBASE服务器启动与关闭

HBASE比赛用服务器启动 (1)在主节点执行命令【cd /usr/local/hadoop/sbin】进入目录,执行命令 【./start-dfs.sh】、【./start-yarn.sh】、【./mr-jobhistory-daemon.sh start historyserver】 启动集群。 (2) 在主节点执行命令【ntp_update】启动时间同步服务(不用,开机自启) (3) 执行命令【service mysqld start】启动 MySQL 服务(不用,开机自启) (4) 通过执行目录/u

weixin_43621549的博客 3627

【数字孪生与仿真技术】10:半导体制造中的虚拟量测技术深度解析:从多尺度建模到工业级应用

摘要:半导体制造过程中,晶圆加工需实时监测300+关键参数,传统物理量测技术面临产能损耗、延迟检测等痛点。本文系统阐述虚拟量测(Virtual Metrology)技术的完整解决方案,通过多尺度混合建模实现物理机理与数据驱动的深度融合。内容涵盖等离子体刻蚀、薄膜沉积等关键工艺的物理模型构建,LSTM神经网络的数据校正算法,以及边缘-云协同的实时部署架构。某12英寸晶圆厂实践表明,虚拟量测技术可减少70%物理量测频次,异常漏检率从18%降至3%,机台利用率提升11%。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2552

Python全栈入门到实战【进阶篇 1】类与对象:面向对象编程的基石

Python中定义类使用**class关键字**,创建对象使用**类名()**(类似调用函数),语法简洁,我们从最基础的空类开始,逐步拆解。class# 定义空的学生类,pass表示占位,无实际内容 class Student : pass编码规范:类名遵循大驼峰命名法(每个单词首字母大写,无下划线),如StudentCarPhone,这是Python官方推荐的PEP8规范,便于区分类和其他标识符。实例方法必须定义在类内部;实例方法的第一个参数必须是self(名称可自定义,如this。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 3405

HBase环境搭建与使用

环境 hadoop集群 zookeeper单机 hbase单机 开发环境可以关注 “后端码匠” 回复 电脑环境 获取 ,也可自行下载,也很快的,另外可加群讨论???? 环境变量 #JAVA_HOME export JAVA_HOME=/usr/java/jdk1.8.0_221 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar #HADOOP_HOME

微信公众号: 后端码匠 936

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

编程中,有哪些好的习惯一开始就值得坚持?(转载)

嗨,小伙伴们大家好,我是沉默王二,就是那个吹自己既有颜值又有才华的家伙。今天这个话题我觉得还是值得和大家探讨的,因为好的编程习惯对程序员的职业生涯真的非常重要。 记得我在学驾照的时候,遇到一哥们,之前开过车,属于无证驾驶的那种。但是,这哥们科目二竟然挂了四次,第五次有没有过我不知道,因为我科目三都考过了,那哥们还在练科目二。教练真气的不轻,天天扯着嗓门喊:“你那个脑袋瓜子特么能不能不要钻到车窗外面看,把车窗玻璃给我摇上去,里面难道看不到镜子吗?” 我在排队等车期间真的观察过,尤其是侧方停车的时候,这哥们总是

Solomwn的博客 247

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

转载----如何阅读代码?

如何阅读代码

m0_38036750的博客 114

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

如何阅读别人的代码?(转载)

本篇回答内容来自优快云博主祝枫 适用于注释不明确、技术文档确实,读代码如读天书的人群。消除恐惧与抵制情绪,从方法论开始,有明确的读代码的思路。 为什么要学会读别人的代码? 提升编程技能,学习他人优秀的编程风格; 研究某方面的功能和技术,项目源码中已有该技术或者功能的实现,根据源码“逆向工程” 吃饭的本领 高效阅读源代码方法 熟悉项目编程语言的语法和惯用语 看项目文档,向开发人员请教 自上而下的构建项目程序的系统框架结构 基本流程: 主函数->其他函数 主要功能->次要功能 根据函数的名字以

weixin_42098322的博客 269

【糟糕程序员的 20 个坏习惯】【转载】

以上这些不良习惯,你命中几个呢?或者你身边有没有碰到这样的人?我认为提早规避这些问题,是成为一个优秀程序员必须要做的。这些习惯总结起来大致分为这 4 个方面:良好的编程修养谦虚的学习心态良好的沟通和表达注重团队协作优秀程序员的专业技能,我们可能很难在短时间内学会,但这些基本的职业素养,是可以在短期内做到的。希望你我可以有则改之,无则加勉。你认为还有哪些程序员的坏习惯,欢迎在评论区留言讨论~糟糕程序员的 20 个坏习惯。

j8267643的博客 927

如何阅读别人的代码[转载]

 如何阅读别人的代码[转载]  ++++++++++++ 第一章: 导论 ++++++++++++  1.要养成一个习惯, 经常花时间阅读别人编写的高品质代码. 2.要有选择地阅读代码, 同时, 还要有自己的目标. 您是想学习新的模式|编码风格|还是满足某些需求的方法. 3.要注意并重视代码中特殊的非功能性需求, 这些需求也许会导致特殊的实现风格.

Redwind的专栏 448

FCS阅读笔记:良好的编程习惯

FCS阅读笔记:良好的编程习惯作者:Liu21st  时间:2004-8-18  文档类型:转载  来自:Liu21sts Blog浏览统计 year:3737 | Quarter:548 | Month:548 | Week:105 | today:14本节内容概述了在使用actionscript编程和创建应用程序的时候需要遵循的一些

Java Coffee Bar 1341

不良的变成习惯(转载)

不良的编程习惯1:抄袭复制代码 在工作中,规则不太清楚。当然,有些代码块不应该被盗。如果它来自专有代码,请不要将其折叠到您的堆栈中,尤其是当它标记有版权信息时。编写自己的版本。这就是他们付钱给您的事情。 当原始创作者想要共享时,棘手的问题就来了。也许是在那些在线编程论坛之一上。也许它是带有许可证(BSD,MIT)的开放源代码,允许使用一个或三个功能。没有法律理由阻止您。而且您有报酬解决问题,而不是...

ailinyingai的博客 206

阅读别人的代码,是一种怎样的体验

原创:微信公众号 【阿Q说代码】,欢迎分享,转载请保留出处。 之前写过一篇名为《看了同事写的代码,我竟然开始默默的模仿了。。。》的文章,今天偶然间看了下后台数据,大吃一惊。该文章的阅读量在微信公众号内竟然达到了惊人的5W+ 。对于没见过市面的我来说已经相当满足了。 当然,能达到这样的数据离不开各位大佬的垂青,在此再次感谢各位大佬。 于是我又抱着好奇的态度去其他平台看了下数据,感觉也不错,大体算了一下全网竟然达到了10W+——此处应有掌声,为自己鼓个掌。 后面如果还有大佬想转载这篇文章,可以第一时间联系.

阿Q的小窝 490

如何快速阅读源代码

如何快速阅读源代码 这篇文章,是对我自己常用阅读源码的习惯的总结。 (零):先做备份 当拿到一份源代码,不管是工作上临时接手的项目还是平时在网站上down下来的demo,如果想要完全看懂,往往需要做一些改动,有时候改动的比较...

285

如何阅读大型设计代码

最近刚刚接到一个有关CAN总线控制器的程序,领导只是说先看,但没说看完之后要干嘛,猜测可能是后面需要调试板卡对接通信。 由于之前没有了解过CAN总线,因此这又是一次从零开始的摸索。 之前自己写过的程序虽然也不比这个程序的规模小,但是困难主要存在于以下几点: CAN总线的概念不了解(理论知识) 不清楚该CAN总线控制器模块的功能和通信对象 这是别人写的程序(编写习惯、命名习惯等),阅读起来有难度 一、了解概念 对于第一点,通常阅读相关理论介绍的博客,配合知网上面相关硕博士论文的引言加前两章理论背景介绍就可

weixin_40634003的博客 341

(转载)如何看代码

链接,不是原址,也是转载:http://blog.sina.com.cn/s/blog_a4cdf30501016j2b.html -----------------------------------------------------手动备份-------------------------------------------------------------- 看代码是一个一流的程

bilifo的博客 1037

linux源代码阅读工具(转载)

http://blog.youkuaiyun.com/bruce0532/article/details/7865800 Windows下的源码阅读工具Souce Insight凭 借着其易用性和多种编程语言的支持,无疑是这个领域的“带头大哥”。Linux/UNIX环境下呢?似乎仍然是处于百花齐放,各有千秋的春秋战国时代,实 际上,似乎其环境下的任何软件都是处于一种逐鹿中原的态势,也许这就是“集市”之于“大教

limanjihe的专栏 3807

怎么么阅读代码

阅读大型代码

Arvin_ing的博客 276

阅读笔记6 -代码阅读与实践

通过阅读这本书,我对阅读代码有了很大的理解能力,并且在以后编程的过程中能够更多的去改善自己的代码可以让自己的代码更加容易让其他人看明白。 阅读代码,应当首先看文档,看得越全越好,软件手册、命名规范、设计说明等非代码能够通读一遍。 仔细查看代码文件夹、包的组织结构 理解编译配置,认识代码中可能使用到的类库 掌握语言特性和常用数据结构,书中以C语言为例,指针的详细使用场景,书中举了10多种指针...

weixin_30856965的博客 78
上一篇: 程序员如何进阶(转载)
下一篇: Linux操作系统中内存buffer和cache的区别
firstephen
博客等级 码龄18年 7粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值