`
han_zw
  • 浏览: 174433 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

hadoop 2.7.2 yarn中文文档——编写 YARN Applications

 
阅读更多
目标
本文在较高层次介绍实现YARN的application的方式。
 概念和流程
通俗讲就是一个application提交客户端提交一个application到YARN Resource Manager(RM)。通过建立YarnClient对象可以完成这个工作。YarnClient启动之后,client之后可以建立application context,准备包含ApplicationMaster(AM)的第一个container,之后提交该application。你需要提供你的application运行所需的详细信息,包括本地文件、jar文件、实际运行的命令(包括必要的命令行参数)、任意操作系统环境变量设置等等。实际上,你需要做的就是描述启动你的ApplicationMaster的Unix 进程。
YARN ResourceManager之后将会在已分配的container中启动特定的ApplicationMaster。Application Master负责与YARN集群通信,并且处理appication的执行。它执行操作采用异步模式。在application启动期间,ApplicationMaster的主要任务是:a) 与ResourceManager通信,为下阶段的容器分配资源;b)container分配以后,与 YARN *NodeManager*(NMs)通信以启动application container。 其中任务a可以通过AMRMClientAsync 对象,利用AMRMClientAsync.CallbackHandler类型的event handler中的事件处理方法进行异步处理。event handler需要明确的设置client。任务b在容器被分配后,可以通过部署一个可运行对象来启动container。作为启动container的一部分,AM需要指定包含启动信息(如命令行格式,环境变量等)的ContainerLaunchContext。
在执行一个application过程中,ApplicationMaster 通过NMClientAsync 对象与NodeManagers通信。所有container事件通过与NMClientAsync相关联的NMClientAsync.CallbackHandler处理。典型的callback handler处理client start,stop,status update和error事件。ApplicatonMaster也通过AMRMClientAsync.CallbackHandler的getProgress()方法给ResourceManager汇报进度。
除了异步client,还有用于特定工作流的同步版本(AMRMClient and NMClient)。推荐使用异步client,因为其用法简单,并且本文将主要介绍异步client。
接口
以下是重要的接口:
  • Client<-->ResourceManager
使用YarnClient 对象。
  • ApplicationMaster<-->ResourceManager
使用AMRMClientAsync对象,利用AMRMClientAsync.CallbackHandler异步处理事件
  • ApplicationMaster<-->NodeManager
启动container.使用NMClientAsync对象与NodeManager通信,通过MClientAsync.CallbackHandler处理container事件。
备注:
  • YARN application的三个主要协议(ApplicationClientProtocol, ApplicationMasterProtocol and ContainerManagementProtocol)依然保留。这三个client封装3个协议,为YARN application提供简单的开发模式。
  • 在非常罕见的情况下,开发者可能想要直接使用这3个协议实现一个application。然而,这样的使用行为在下一代将不再鼓励。
编写一个简单的Yarn Application
 编写简单client
  • Client第一步需要做的就是初始化并启动YarnCient。
YarnClient yarnClient = YarnClient.createYarnClient(); yarnClient.init(conf); yarnClient.start();
  • 一旦client建立完成,client需要创建一个application,获取它的application id。
YarnClientApplication app = yarnClient.createApplication(); GetNewApplicationResponse appResponse = app.getNewApplicationResponse();
  • 来自YarnClientApplication的新application的response额外包含了集群的信息,例如集群的最小/最大 的resource capability.你可以依据此信息正确设定将要启动ApplicationMaster的container。
  • client的主要难点是设置ApplicationSubmissionContext ,它定义了需要RM启动AM需要的所有信息。client需要在context中设置以下信息:
  • Application 信息: id, name。
  • Queue, priority 信息: application将要提交到的目标队列,application分配的优先级。
  • User: 提交application的用户信息。
  • ContainerLaunchContext: 将要启动和运行AM的Container的信息。在之前已经提到,ContainerLaunchContext定义了运行application所有必要信息,例如 local *Resources (二进制, jars, 文件等等.), 环境变量设置 (CLASSPATH 等等.), 执行的Command,以及security Tokens (RECT).

// set the application submission context
ApplicationSubmissionContext appContext = app.getApplicationSubmissionContext();
ApplicationId appId = appContext.getApplicationId();

appContext.setKeepContainersAcrossApplicationAttempts(keepContainers);
appContext.setApplicationName(appName);

// set local resources for the application master
// local files or archives as needed
// In this scenario, the jar file for the application master is part of the local resources
Map<String, LocalResource> localResources = new HashMap<String, LocalResource>();

LOG.info("Copy App Master jar from local filesystem and add to local environment");
// Copy the application master jar to the filesystem
// Create a local resource to point to the destination jar path
FileSystem fs = FileSystem.get(conf);
addToLocalResources(fs, appMasterJar, appMasterJarPath, appId.toString(),
    localResources, null);

// Set the log4j properties if needed
if (!log4jPropFile.isEmpty()) {
  addToLocalResources(fs, log4jPropFile, log4jPath, appId.toString(),
      localResources, null);
}

// The shell script has to be made available on the final container(s)
// where it will be executed.
// To do this, we need to first copy into the filesystem that is visible
// to the yarn framework.
// We do not need to set this as a local resource for the application
// master as the application master does not need it.
String hdfsShellScriptLocation = "";
long hdfsShellScriptLen = 0;
long hdfsShellScriptTimestamp = 0;
if (!shellScriptPath.isEmpty()) {
  Path shellSrc = new Path(shellScriptPath);
  String shellPathSuffix =
      appName + "/" + appId.toString() + "/" + SCRIPT_PATH;
  Path shellDst =
      new Path(fs.getHomeDirectory(), shellPathSuffix);
  fs.copyFromLocalFile(false, true, shellSrc, shellDst);
  hdfsShellScriptLocation = shellDst.toUri().toString();
  FileStatus shellFileStatus = fs.getFileStatus(shellDst);
  hdfsShellScriptLen = shellFileStatus.getLen();
  hdfsShellScriptTimestamp = shellFileStatus.getModificationTime();
}

if (!shellCommand.isEmpty()) {
  addToLocalResources(fs, null, shellCommandPath, appId.toString(),
      localResources, shellCommand);
}

if (shellArgs.length > 0) {
  addToLocalResources(fs, null, shellArgsPath, appId.toString(),
      localResources, StringUtils.join(shellArgs, " "));
}

// Set the env variables to be setup in the env where the application master will be run
LOG.info("Set the environment for the application master");
Map<String, String> env = new HashMap<String, String>();

// put location of shell script into env
// using the env info, the application master will create the correct local resource for the
// eventual containers that will be launched to execute the shell scripts
env.put(DSConstants.DISTRIBUTEDSHELLSCRIPTLOCATION, hdfsShellScriptLocation);
env.put(DSConstants.DISTRIBUTEDSHELLSCRIPTTIMESTAMP, Long.toString(hdfsShellScriptTimestamp));
env.put(DSConstants.DISTRIBUTEDSHELLSCRIPTLEN, Long.toString(hdfsShellScriptLen));

// Add AppMaster.jar location to classpath
// At some point we should not be required to add
// the hadoop specific classpaths to the env.
// It should be provided out of the box.
// For now setting all required classpaths including
// the classpath to "." for the application jar
StringBuilder classPathEnv = new StringBuilder(Environment.CLASSPATH.$$())
  .append(ApplicationConstants.CLASS_PATH_SEPARATOR).append("./*");
for (String c : conf.getStrings(
    YarnConfiguration.YARN_APPLICATION_CLASSPATH,
    YarnConfiguration.DEFAULT_YARN_CROSS_PLATFORM_APPLICATION_CLASSPATH)) {
  classPathEnv.append(ApplicationConstants.CLASS_PATH_SEPARATOR);
  classPathEnv.append(c.trim());
}
classPathEnv.append(ApplicationConstants.CLASS_PATH_SEPARATOR).append(
  "./log4j.properties");

// Set the necessary command to execute the application master
Vector<CharSequence> vargs = new Vector<CharSequence>(30);

// Set java executable command
LOG.info("Setting up app master command");
vargs.add(Environment.JAVA_HOME.$$() + "/bin/java");
// Set Xmx based on am memory size
vargs.add("-Xmx" + amMemory + "m");
// Set class name
vargs.add(appMasterMainClass);
// Set params for Application Master
vargs.add("--container_memory " + String.valueOf(containerMemory));
vargs.add("--container_vcores " + String.valueOf(containerVirtualCores));
vargs.add("--num_containers " + String.valueOf(numContainers));
vargs.add("--priority " + String.valueOf(shellCmdPriority));

for (Map.Entry<String, String> entry : shellEnv.entrySet()) {
  vargs.add("--shell_env " + entry.getKey() + "=" + entry.getValue());
}
if (debugFlag) {
  vargs.add("--debug");
}

vargs.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/AppMaster.stdout");
vargs.add("2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/AppMaster.stderr");

// Get final commmand
StringBuilder command = new StringBuilder();
for (CharSequence str : vargs) {
  command.append(str).append(" ");
}

LOG.info("Completed setting up app master command " + command.toString());
List<String> commands = new ArrayList<String>();
commands.add(command.toString());

// Set up the container launch context for the application master
ContainerLaunchContext amContainer = ContainerLaunchContext.newInstance(
  localResources, env, commands, null, null, null);

// Set up resource type requirements
// For now, both memory and vcores are supported, so we set memory and
// vcores requirements
Resource capability = Resource.newInstance(amMemory, amVCores);
appContext.setResource(capability);

// Service data is a binary blob that can be passed to the application
// Not needed in this scenario
// amContainer.setServiceData(serviceData);

// Setup security tokens
if (UserGroupInformation.isSecurityEnabled()) {
  // Note: Credentials class is marked as LimitedPrivate for HDFS and MapReduce
  Credentials credentials = new Credentials();
  String tokenRenewer = conf.get(YarnConfiguration.RM_PRINCIPAL);
  if (tokenRenewer == null | | tokenRenewer.length() == 0) {
    throw new IOException(
      "Can't get Master Kerberos principal for the RM to use as renewer");
  }

  // For now, only getting tokens for the default file-system.
  final Token<?> tokens[] =
      fs.addDelegationTokens(tokenRenewer, credentials);
  if (tokens != null) {
    for (Token<?> token : tokens) {
      LOG.info("Got dt for " + fs.getUri() + "; " + token);
    }
  }
  DataOutputBuffer dob = new DataOutputBuffer();
  credentials.writeTokenStorageToStream(dob);
  ByteBuffer fsTokens = ByteBuffer.wrap(dob.getData(), 0, dob.getLength());
  amContainer.setTokens(fsTokens);
}

appContext.setAMContainerSpec(amContainer);
 
  • 设置过程完成之后,client已经准备好提交application(设置了优先级和队列)。
// Set the priority for the application master
Priority pri = Priority.newInstance(amPriority);
appContext.setPriority(pri);

// Set the queue to which this application is to be submitted in the RM
appContext.setQueue(amQueue);

// Submit the application to the applications manager
// SubmitApplicationResponse submitResp = applicationsManager.submitApplication(appRequest);

yarnClient.submitApplication(appContext);
 
  • 在这个时候,RM在后台已经接受了application,之后分配满足资源需求的container并建立之,然后在分配的container中启动AM。
  • client有多种方式跟踪实际任务的进度.
  • 它可以通过YarnClient的getApplicationReport()方法与RM通信,请求application的report。
// Get application report for the appId we are interested in
ApplicationReport report = yarnClient.getApplicationReport(appId);
 
接受到的ApplicationReport由如下内容组成:
  • 通用Application信息: Application id, application提交到的队列,提交application的用户,application的启动时间。
  • AM运行的host,监听client请求的rpc端口,client需要与AM通信的token。
  • Application tracking 信息: 如果application支持某种形式的进度跟踪,它可以设置tracking url,client通过ApplicationReport的getTrackingUrl()方法可以监控进度。
  • Application状态 :application的状态可以通过ApplicationReport#getYarnApplicationState看到。如果YarnApplicationState 被设置为FINISHED,client应该参考ApplicationReport#getFinalApplicationStatus 来检查application任务实际的成功/失败。如果是失败的情况,ApplicationReport#getDiagnostics可能包含一些失败的原因或者提示。
  • 如果ApplicationMaster支持,client可以直接通过application report中的 host:rpcport信息查询AM自身获取进度更新。当然也可以使用report中的tracking url查看进度。
  • 在通常情况下,如果application耗时太长,或者因为其他原因,client可能希望杀死该application。YarnClient支持killApplication ,即允许client通过ResourceManager发送一个kill信号到AM。ApplicationMaster也可以设计为支持通过它的rpc层的abort调用,client可以直接通过该手段进行操作。
yarnClient.killApplication(appId);
 
编写ApplicationMaster (AM)
  • AM是job的实际owner。它通过client提供job的所有必要信息和资源,并由RM启动、监管和完成。
  • 作为AM,它在container中启动,该container可能是与其他container共享同一个物理主机,考虑到多租户的性质,除其他问题外,它不能作出任何假设的东西,如预先配置的监听端口。
  • 在AM启动时,几个环境变量中的参数对其是可用的。这些包括AM container的ContainerId,application的提交时间,运行ApplicationMaster的NM(NodeManager)的详情。
  • 与RM的交互需要一个ApplicationAttemptId (每个application在失败的情况下可以有多个attempt)。ApplicationAttemptId 可以通过AM的container id获取。有一些工具性的API可以将从环境变量获得的值转换为对象。
Map<String, String> envs = System.getenv();
String containerIdString =
    envs.get(ApplicationConstants.AM_CONTAINER_ID_ENV);
if (containerIdString == null) {
  // container id should always be set in the env by the framework
  throw new IllegalArgumentException(
      "ContainerId not set in the environment");
}
ContainerId containerId = ConverterUtils.toContainerId(containerIdString);
ApplicationAttemptId appAttemptID = containerId.getApplicationAttemptId();
 
  • AM初始化完成之后,我们可以启动这两个client:一个是与ResourceManager交互,一个是与NodeManagers交互。我们启动它们并赋予定制化的event handler,稍后本文会详细介绍这些event handler。
AMRMClientAsync.CallbackHandler allocListener = new RMCallbackHandler();
  amRMClient = AMRMClientAsync.createAMRMClientAsync(1000, allocListener);
  amRMClient.init(conf);
  amRMClient.start();

  containerListener = createNMCallbackHandler();
  nmClientAsync = new NMClientAsyncImpl(containerListener);
  nmClientAsync.init(conf);
  nmClientAsync.start();
 
  • AM不得不向RM发出心跳以表名AM是存活的。在RM端超时时间间隔设置通过访问YarnConfiguration.RM_AM_EXPIRY_INTERVAL_MS获得,默认值通过YarnConfiguration.DEFAULT_RM_AM_EXPIRY_INTERVAL_MS设置。ApplicationMaster需要注册自身到ResourceManager以启动心跳。
// Register self with ResourceManager
// This will start heartbeating to the RM
appMasterHostname = NetUtils.getHostname();
RegisterApplicationMasterResponse response = amRMClient
    .registerApplicationMaster(appMasterHostname, appMasterRpcPort,
        appMasterTrackingUrl);
 
  • 在注册的应答信息中,可能包含最大资源容量,你可以使用这个信息来校验application的请求。
// Dump out information about cluster capability as seen by the
// resource manager
int maxMem = response.getMaximumResourceCapability().getMemory();
LOG.info("Max mem capabililty of resources in this cluster " + maxMem);

int maxVCores = response.getMaximumResourceCapability().getVirtualCores();
LOG.info("Max vcores capabililty of resources in this cluster " + maxVCores);

// A resource ask cannot exceed the max.
if (containerMemory > maxMem) {
  LOG.info("Container memory specified above max threshold of cluster."
      + " Using max value." + ", specified=" + containerMemory + ", max="
      + maxMem);
  containerMemory = maxMem;
}

if (containerVirtualCores > maxVCores) {
  LOG.info("Container virtual cores specified above max threshold of  cluster."
    + " Using max value." + ", specified=" + containerVirtualCores + ", max="
    + maxVCores);
  containerVirtualCores = maxVCores;
}
List<Container> previousAMRunningContainers =
    response.getContainersFromPreviousAttempts();
LOG.info("Received " + previousAMRunningContainers.size()
        + " previous AM's running containers on AM registration.");
 
  • 基于task请求,AM可以申请一组container来运行它的tasks。我们现在能计算出需要多少container,按需请求container。
List<Container> previousAMRunningContainers =
    response.getContainersFromPreviousAttempts();
List<Container> previousAMRunningContainers =
    response.getContainersFromPreviousAttempts();
LOG.info("Received " + previousAMRunningContainers.size()
    + " previous AM's running containers on AM registration.");

int numTotalContainersToRequest =
    numTotalContainers - previousAMRunningContainers.size();
// Setup ask for containers from RM
// Send request for containers to RM
// Until we get our fully allocated quota, we keep on polling RM for
// containers
// Keep looping until all the containers are launched and shell script
// executed on them ( regardless of success/failure).
for (int i = 0; i < numTotalContainersToRequest; ++i) {
  ContainerRequest containerAsk = setupContainerAskForRM();
  amRMClient.addContainerRequest(containerAsk);
}
 
  • 在setupContainerAskForRM()中,以下两项需要设置:
  • Resource capability: 目前,YARN支持基于内存的资源请求,所以请求信息应该定义需要多少内存。该值需要以MB为单位定义,而且要小于集群的最大容量,并且是最小容量的精确倍数。内存资源会对应于task container所在的物理资源限制。YARN还支持基于计算核模型(vCore)资源,这会在代码中演示。
  • Priority: 当申请一组container时,AM可能会为其中每一个定义不同的优先级。例如,Map-Reduce AM会为Map task的container分配较高的优先级,而对Reduce task container分配较低优先级。
private ContainerRequest setupContainerAskForRM() {
  // setup requirements for hosts
  // using * as any host will do for the distributed shell app
  // set the priority for the request
  Priority pri = Priority.newInstance(requestPriority);

  // Set up resource type requirements
  // For now, memory and CPU are supported so we set memory and cpu requirements
  Resource capability = Resource.newInstance(containerMemory,
    containerVirtualCores);

  ContainerRequest request = new ContainerRequest(capability, null, null,
      pri);
  LOG.info("Requested container ask: " + request.toString());
  return request;
}
 
  • application manager发送container allocation request之后,通过AMRMClientAsync的event handler异步启动container。handler需要实现AMRMClientAsync.CallbackHandler interface接口。
  • 当有container被分配时,handler需要设置一个线程来启动container。这里我们使用LaunchContainerRunnable 来演示。我们将在下面的章节中讨论LaunchContainerRunnable 。
@Override
public void onContainersAllocated(List<Container> allocatedContainers) {
  LOG.info("Got response from RM for container ask, allocatedCnt="
      + allocatedContainers.size());
  numAllocatedContainers.addAndGet(allocatedContainers.size());
  for (Container allocatedContainer : allocatedContainers) {
    LaunchContainerRunnable runnableLaunchContainer =
        new LaunchContainerRunnable(allocatedContainer, containerListener);
    Thread launchThread = new Thread(runnableLaunchContainer);

    // launch and start the container on a separate thread to keep
    // the main thread unblocked
    // as all containers may not be allocated at one go.
    launchThreads.add(launchThread);
    launchThread.start();
  }
}
 
  • 在心跳过程中,event handler上报application的进度。
@Override
public float getProgress() {
  // set progress to deliver to RM on next heartbeat
  float progress = (float) numCompletedContainers.get()
      / numTotalContainers;
  return progress;
}
 
  • container启动线程实际执行在NMs启动container的工作。在container分配到AM之后,它需要遵循类似的处理过程——client为将要在分配的container中运行的task设置ContainerLaunchContext。一旦ContainerLaunchContext 定义,AM可以通过NMClientAsync启动container。
// Set the necessary command to execute on the allocated container
Vector<CharSequence> vargs = new Vector<CharSequence>(5);

// Set executable command
vargs.add(shellCommand);
// Set shell script path
if (!scriptPath.isEmpty()) {
  vargs.add(Shell.WINDOWS ? ExecBatScripStringtPath
    : ExecShellStringPath);
}

// Set args for the shell command if any
vargs.add(shellArgs);
// Add log redirect params
vargs.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout");
vargs.add("2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr");

// Get final commmand
StringBuilder command = new StringBuilder();
for (CharSequence str : vargs) {
  command.append(str).append(" ");
}

List<String> commands = new ArrayList<String>();
commands.add(command.toString());

// Set up ContainerLaunchContext, setting local resource, environment,
// command and token for constructor.

// Note for tokens: Set up tokens for the container too. Today, for normal
// shell commands, the container in distribute-shell doesn't need any
// tokens. We are populating them mainly for NodeManagers to be able to
// download anyfiles in the distributed file-system. The tokens are
// otherwise also useful in cases, for e.g., when one is running a
// "hadoop dfs" command inside the distributed shell.
ContainerLaunchContext ctx = ContainerLaunchContext.newInstance(
  localResources, shellEnv, commands, null, allTokens.duplicate(), null);
containerListener.addContainer(container.getId(), container);
nmClientAsync.startContainerAsync(container, ctx);
 
  • NMClientAsync对象与它的event handler一起处理container的event。包括container 启动,停止,状态变更以及发生错误的事件。
  • 在ApplicationMaster决定work已经完成之后,它需要通过 AM-RM client注销自身,之后停止client。
try {
  amRMClient.unregisterApplicationMaster(appStatus, appMessage, null);
} catch (YarnException ex) {
  LOG.error("Failed to unregister application", ex);
} catch (IOException e) {
  LOG.error("Failed to unregister application", e);
}

amRMClient.stop();
 
FAQ
我怎么部署我的application的jar到需要它的YARN集群中的节点上?
你可以使用LocalResource 来添加resource到你的application request中。这样YARN会部署该resource到ApplicationMaster node。如果resource是tgz,zip或者jar——你可以用YARN解压。那么,你所需要做的就是添加解压文件夹到你的classpath。举个例子,当创建你的application请求时:
File packageFile = new File(packagePath);
Url packageUrl = ConverterUtils.getYarnUrlFromPath(
    FileContext.getFileContext.makeQualified(new Path(packagePath)));

packageResource.setResource(packageUrl);
packageResource.setSize(packageFile.length());
packageResource.setTimestamp(packageFile.lastModified());
packageResource.setType(LocalResourceType.ARCHIVE);
packageResource.setVisibility(LocalResourceVisibility.APPLICATION);

resource.setMemory(memory);
containerCtx.setResource(resource);
containerCtx.setCommands(ImmutableList.of(
    "java -cp './package/*' some.class.to.Run "
    + "1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout "
    + "2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr"));
containerCtx.setLocalResources(
    Collections.singletonMap("package", packageResource));
appCtx.setApplicationId(appId);
appCtx.setUser(user.getShortUserName);
appCtx.setAMContainerSpec(containerCtx);
yarnClient.submitApplication(appCtx);
 
就像你看到的,setLocalResources 命令传入了一个该resource的map。map中的name在你的application工作目录中变成一个符号链接,所以你可以用./package/*的方式访问构件中的内容。
Note: java的classpath参数是大小写敏感的,确保你的语法完全正确。
我怎么获得ApplicationMaster的ApplicationAttemptId?
ApplicationAttemptId 会通过环境变量传入AM,通过ConverterUtils 的工具方法可以将该值可以转换为ApplicationAttemptId 对象。
为什么我的container被NodeManager杀死了?
这有可能是因为内存使用过高,超过了你申请的container的内存大小。有很多原因会引起这个问题。首先,查看NodeManager杀死你的container时dump出来的进程树。如果你已经超过了物理内存限制,那说明你的app使用了太多的物理内存。如果你运行的一个java app,你可以使用-hprof 来查看是什么占用了heap的空间。如果你已经超出了虚拟内存,则可能需要增加集群配置的变量yarn.nodemanager.vmem-pmem-ratio的值。
How do I include native libraries?
在启动container的命令行中设置-Djava.library.path会引起hadoop使用的native libraries不能被正确加载,最终会导致错误。简洁的用法是使用LD_LIBRARY_PATH 。
分享到:
评论

相关推荐

    PPT模板 -龙湖新员工转正答辩模板.pptx

    PPT模板 -龙湖新员工转正答辩模板.pptx

    PPT模板 -生产计划管理.pptx

    PPT模板 -生产计划管理.pptx

    生产单元数字化改造23年国赛

    生产单元数字化改造23年国赛

    ECharts柱状图-极坐标系下的堆叠柱状图2.rar

    图表效果及代码实现讲解链接:https://blog.csdn.net/zhangjiujiu/article/details/143997013

    机器人算法的 Python 示例代码 .zip

    Pythonbot高斯网格图射线投射网格图激光雷达至网格地图k-均值对象聚类矩形接头大满贯迭代最近点 (ICP) 匹配FastSLAM 1.0路径规划动态窗口方法基于网格的搜索Dijkstra 算法A* 算法D*算法D* Lite 算法位场算法基于网格的覆盖路径规划国家网格规划偏极采样车道采样概率路线图(PRM)规划快速探索随机树(RRT)回程时间*RRT* 和 reeds-shepp 路径LQR-RRT*五次多项式规划Reeds Shepp 规划基于LQR的路径规划Frenet 框架中的最佳轨迹路径追踪移动到姿势控制斯坦利控制后轮反馈控制线性二次调节器 (LQR) 速度和转向控制模型预测速度和转向控制采用 C-GMRES 的非线性模型预测控制手臂导航N关节臂对点控制带避障功能的手臂导航航空导航无人机三维轨迹跟踪火箭动力着陆双足动物倒立摆双

    sql综合学习基础知识及练习题考试题实测题.zip

    SQL,全称为结构化查询语言(Structured Query Language),是用于管理和操作关系型数据库的标准化语言。它广泛应用于数据插入、查询、更新和删除等操作,并且拥有超过40年的历史,证明了其在数据处理领域的核心地位。以下是对SQL综合学习基础知识及练习题考试题实测题的介绍

    java面向对象 - 类与对象.doc

    java面向对象 - 类与对象 在Java编程语言中,面向对象编程(OOP)是一个核心概念。它强调以对象作为程序的基本单位,并将相关的数据和功能封装在对象中。类和对象是Java OOP的两个关键组成部分。 ### 类(Class) 类是一个模板或蓝图,它定义了对象的属性和行为。我们可以将类视为对象的类型或种类。通过类,我们可以创建(实例化)具有特定属性和行为的对象。 类的组成部分通常包括: 1. **成员变量**(属性):用于存储对象的状态或数据。 2. **方法**(行为):定义了对象可以执行的操作或功能。 3. **构造方法**:一种特殊类型的方法,用于在创建对象时初始化其状态。 4. **块**(如静态块、实例初始化块):用于执行类级别的初始化代码。 5. **嵌套类**:一个类可以包含其他类,这被称为嵌套或内部类。 ### 对象(Object) 对象是类的实例。它是根据类模板创建的具体实体,具有自己的状态和行为。每个对象都是其类的一个唯一实例,可以访问其类中定义的属性和方法。 创建对象的过程通常涉及以下几个步骤: 1. **声明**:指定对象的类型(即其所属的类

    原生JS实现鼠标感应图片左右滚动代码.zip

    原生JS实现鼠标感应图片左右滚动代码.zip

    随机密码生成器,支持字符、数字、字母大小写组合

    随机密码生成器,支持字符、数字、字母大小写组合

    自动化部署管道创建的代码库(含 Concourse 和 Jenkins 相关).zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。

    高等工程数学试题详解:矩阵分析与最优化方法

    内容概要:本文档为一份高级数学复习试题,内容涵盖线性代数、数值分析及最优化理论等领域,主要包括矩阵范数的计算、遗传算法中的变异操作、内点法解非线性优化问题、证明矩阵有互异特征值、求解矩阵的标准形以及应用单纯形法和FR共轭梯度法解决具体的数学问题等方面。 适合人群:正在备考研究生入学考试或者准备参加各类数学竞赛的学生、对高等数学感兴趣的学习者及从事相关领域科研工作的专业人士。 使用场景及目标:用于巩固和检验个人关于矩阵论、优化方法及概率统计的知识掌握情况,帮助应试者系统地复习相关考点,提高解题技巧。 阅读建议:建议结合具体题目深入理解每一个概念及其应用方式,遇到复杂的计算或证明步骤不妨动手尝试推导一次,这样有助于加深记忆并培养灵活运用知识的能力。同时,在理解算法原理的基础上,还可以参考一些实际案例来进行练习。

    使用了脉冲码调制(PCM).计算了所需的比特率和信号量化误差Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Google 表格 Python API.zip

    Google Spreadsheet Python API v4Google Sheets 配合使用的简单界面。特征通过标题、关键字或URL打开电子表格。读取、写入和格式化单元格区域。共享和访问控制。批量更新。安装pip install gspread要求Python 3.8+。基本用法在 Google API 控制台中创建凭据开始使用 gspreadimport gspreadgc = gspread.service_account()# Open a sheet from a spreadsheet in one gowks = gc.open("Where is the money Lebowski?").sheet1# Update a range of cells using the top left corner addresswks.update([[1, 2], [3, 4]], "A1")# Or update a single cellwks.update_acell("B42", "it's

    AICon 2024全球人工智能开发与应用大会(脱敏)PPT合集(30份).zip

    AICon 2024全球人工智能开发与应用大会(脱敏)PPT合集,共30份。 AI辅助编程测评与企业实践 SmartEV和AI 蔚来的思考与实践 下一代 RAG 引擎的技术挑战与实现 书生万象大模型的技术演进与应用探索 人工智能行业数据集构建及模型训练方法实践周华 全方位评测神经网络模型的基础能力 千亿参数 LLM 的训练效率优化 向量化与文档解析技术加速大模型RAG应用落地 基于大模型的缺陷静态检查 多环境下的 LLM Agent 应用与增强 大模型在华为推荐场景中的探索和应用 大模型在推荐系统中的落地实践 大模型的异构计算和加速 大模型辅助需求代码开发 大语言模型在法律领域的应用探索 大语言模型在计算机视觉领域的应用 大语言模型的幻觉检测 小米大模型端侧部署落地探索 快手可图大模型的技术演进与应用探索 提升大模型知识密度,做高效的终端智能 电商大模型及搜索应用实践 百度大模型 原生安全构建之路 硅基流动高性能低成本的大模型推理云实践 语言模型驱动的软件工具思考:可解释与可溯源 长文本大模型推理实践:以 KVCache 为中心的分离式推理架构 阿里云 AI 搜索 RAG 大模型优

    子弹打穿金属后留下弹痕flash动画.zip

    子弹打穿金属后留下弹痕flash动画.zip

    雷达目标一维距离像仿真实验,以及多目标成像 matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    原生js竖直动画手风琴下拉菜单代码.zip

    原生js竖直动画手风琴下拉菜单代码.zip

    受循环荷载作用的土壤或路面层分析Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Centos6.x通过RPM包升级OpenSSH9.7最新版 升级有风险,前务必做好快照,以免升级后出现异常影响业务

    Centos6.x通过RPM包升级OpenSSH9.7最新版 升级有风险,前务必做好快照,以免升级后出现异常影响业务

    营销策划 -阿道夫洗护品牌新品小红书新品营销方案.pptx

    营销策划 -阿道夫洗护品牌新品小红书新品营销方案.pptx

Global site tag (gtag.js) - Google Analytics