Apex开发注意事项

Oracle-APEX开发指南(1) 难道密码不对,于是再次更改ADMIN的密码,重启数据库,发现问题依旧,这样排除了ADMIN密码不对的可能,APEX授权的登录连接只有APEX_04002,这个也是没有问题的,也就是说本次的安装都是OK的,毕竟系统都启起来了,这时候联想到是不是这个授权验证是否还走的是之前的3.0版本的校验,执行了如下这段SQL发现确实还存在之前3.0版本的遗留用户,果断的把这些用户全部drop掉。每个页面的结果都在新的会话中,因此当Application Express引擎处理或者呈现一个页面的时候才会消耗数据库资源。 阅读详情

Apex开发注意事项

*https://developer.salesforce.com/page/Apex_Code_Best_Practices

Best Practice #1: 在Trigger里成块儿的处理数据集

Bad Sample

trigger accountTestTrggr on Account (before insert, before update) {
   Account acct = Trigger.new[0];
   List<Contact> contacts = [select id, salutation, firstname, lastname, email 
              from Contact where accountId = :acct.Id];
   
}

Good Sample

trigger accountTestTrggr on Account (before insert, before update) {
   List<String> accountNames = new List<String>{};
   for(Account a: Trigger.new){
      a.Description = a.Name + ':' + a.BillingState
   }
}

知识点:Trigger的使用场景有两种
一种是画面单条记录更新,新建的时候会触发相应动作的Trigger,这个时候上边儿两个例子处理是一样的都没有问题。
另外一种情况是使用Dataloader活着其他的工作批量的导入数据时候也会触发相应的Tirgger,这时候Bad Sample的处理只能处理第一条(Trigger.new[0]),其他的数据就会丢失(准确的说是每200条,或者一个批处理的第一条),所以正确的做法是用处理数组的方法处理Trigger的逻辑。

Best Practice #2: 不要把SOQL语句写到循环里

Bad Sample

trigger accountTestTrggr on Account (before insert, before update) {
   for(Account a: Trigger.new) {
      List<Contact> contacts = [select id, salutation, firstname, lastname, email  from Contact where accountId = :a.Id];
 		  
      for(Contact c: contacts) {
         System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '], LastName[' + c.lastname +']');
         c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;  
         update c;
      }    	  
   }
}

Good Sample

trigger accountTestTrggr on Account (before insert, before update) {
  List<Account> accountsWithContacts = [select id, name, (select id, salutation, description, firstname, lastname, email from Contacts) 
 from Account where Id IN :Trigger.newMap.keySet()];
  
  List<Contact> contactsToUpdate = new List<Contact>{};
  for(Account a: accountsWithContacts){
     for(Contact c: a.Contacts){
   	  System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '], LastName[' + c.lastname +']');
   	  c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname; 
   	  contactsToUpdate.add(c);
     }    	  
   }
   update contactsToUpdate;
}

知识点:Salesforce的每个事物的执行都是有限制的尤其是SOQL操作有着明确的规定,所以为了避免发生系统异常所以要把SOQL语句拿到循环外边儿,灵活使用List,Map,Set等数组对象,确保在select ,update,Insert等数据库操作语句里只执行一次。
Execution Governors and Limits
Limits Class

Best Practice #3:批量处理数据

确保HelperClass里的执行也是“批量处理数据”的原则来进行书写。
原因是Salesforce里的Limit是按照事物计算的不是按照文件来算的,所以无论是Apex还是Trigger,都应该尽量少的写操作SOQL语句。

Best Practice #4: 尽量给For循环操作提供集合

Bad Sample

trigger accountTrigger on Account (before delete, before insert, before update) {
    List<Opportunity> opptysClosedLost = [select id, name, closedate, stagename
            from Opportunity where  
            accountId IN :Trigger.newMap.keySet() and StageName='Closed - Lost'];
    
    List<Opportunity> opptysClosedWon = [select id, name, closedate, stagename
            from Opportunity where  
            accountId IN :Trigger.newMap.keySet() and StageName='Closed - Won'];
    
    for(Account a : Trigger.new){
    	
        for(Opportunity o: opptysClosedLost){	
    		if(o.accountid == a.id)
    		   System.debug('Do more logic here...');
        }
        
        //Redundantly processes the List of Opportunity Won
        for(Opportunity o: opptysClosedWon){	
    		if(o.accountid == a.id)
    		   System.debug('Do more logic here...');
        }
    }
}
}

Good Sample

trigger accountTrigger on Account (before delete, before insert, before update) {
 
    List<Account> accountWithOpptys = [select id, name, (select id, name, closedate, 
         stagename  from Opportunities  where accountId IN :Trigger.newMap.keySet() 
         and  (StageName='Closed - Lost' or StageName = 'Closed - Won')) 
         from Account where Id IN :Trigger.newMap.keySet()];
    
    //Loop through Accounts only once
    for(Account a : accountWithOpptys){
    	 for(Opportunity o: a.Opportunities){
    	 	if(o.StageName == 'Closed - Won'){
    	 		System.debug('Opportunity Closed Won...do some more logic here...');
    	 	}else if(o.StageName =='Closed - Lost'){
    	 		System.debug('Opportunity Closed Lost...do some more logic here...');
    	 	}
    	 }
    
   }
}

知识点:
好坏相比较来看:
1:SOQL语句少了一个肯定提高效率。
2:嵌套的For循环也减少了一个,改成了If判断的形式来实现了。
Salesforce之所以这么算计效率原因就是因为他是Online的产品,尽可能的减少资源浪费一直是他所推荐的。

Best Practice #5: 做好一个对象上多个Trigger 的排序

原则就是一个事物处理里不要有重复查询同一个数据集的操作。
一种办法是在一个大的Trigger里做好分支判断,保证每个业务的处理逻辑清晰。
另外一种办法是为多个业务做多个Trigger,从而保证Trigger处理数据不被干扰。

Best Practice #6: 使用For循环来查询大数据

Bad Sample

//A runtime exception is thrown if this query returns enough records to exceed your heap limit.
Account[] accts = [SELECT id FROM account];

Good Sample

// Use this format for efficiency if you are executing DML statements 
// within the for loop.  Be careful not to exceed the 150 DML statement limit.
Account[] accts = new Account[];
for (List<Account> acct : [SELECT id, name FROM account
                            WHERE name LIKE 'Acme']) {
    // Your logic here
    accts.add(acct);
}
update accts;

知识点:Salesforce的Limit里还有Heap的异常等等,所以在查询大数据量的同时为了避免出现系统异常建议采用For循环的形式来取得数据,并形成集合对象,最后在进行数据库操作。
因为For循环的处理是取200件处理一次,让后在处理200件,这样不会出现一次取数据过多导致系统异常的问题。

Best Practice #7: 灵活使用 Limits Class来判断和处理Limits的问题

事例代码:

trigger accountLimitExample on Account (after delete, after insert, after update) {

    System.debug('Total Number of SOQL Queries allowed in this Apex code context: ' +  Limits.getLimitQueries());
    System.debug('Total Number of records that can be queried  in this Apex code context: ' +  Limits.getLimitDmlRows());
    System.debug('Total Number of DML statements allowed in this Apex code context: ' +  Limits.getLimitDmlStatements() );
    System.debug('Total Number of CPU usage time (in ms) allowed in this Apex code context: ' +  Limits.getLimitCpuTime());
    
   // Query the Opportunity object 
    List<Opportunity> opptys = 
        [select id, description, name, accountid,  closedate, stagename from Opportunity where accountId IN: Trigger.newMap.keySet()];
   
    System.debug('1. Number of Queries used in this Apex code so far: ' + Limits.getQueries());
    System.debug('2. Number of rows queried in this Apex code so far: ' + Limits.getDmlRows());
    System.debug('3. Number of DML statements used so far: ' +  Limits.getDmlStatements());    
    System.debug('4. Amount of CPU time (in ms) used so far: ' + Limits.getCpuTime());
    if (opptys.size() + Limits.getDMLRows() > Limits.getLimitDMLRows()) {
            System.debug('Need to stop processing to avoid hitting a governor limit. Too many related Opportunities to update in this trigger');
            System.debug('Trying to update ' + opptys.size() + ' opportunities but governor limits will only allow ' + Limits.getLimitDMLRows());
            for (Account a : Trigger.new) {
                a.addError('You are attempting to update the addresses of too many accounts at once. Please try again with fewer accounts.');
            }
    }
    else{
        System.debug('Continue processing. Not going to hit DML governor limits');
        System.debug('Going to update ' + opptys.size() + ' opportunities and governor limits will allow ' + Limits.getLimitDMLRows());
        for(Account a : Trigger.new){
            System.debug('Number of DML statements used so far: ' +  Limits.getDmlStatements());
            for(Opportunity o: opptys){ 
                if (o.accountid == a.id)
                   o.description = 'testing';
            }
        }
        update opptys;
        System.debug('Final number of DML statements used so far: ' +  Limits.getDmlStatements());
        System.debug('Final heap size: ' +  Limits.getHeapSize());
    }
}

DEBUG|Total Number of SOQL Queries allowed in this Apex code context: 100
DEBUG|Total Number of records that can be queried in this Apex code context: 10000
DEBUG|Total Number of DML statements allowed in this Apex code context: 150
DEBUG|Total Number of CPU usage time (in ms) allowed in this Apex code context: 10000
DEBUG|1. Number of Queries used in this Apex code so far: 1
DEBUG|2. Number of rows queried in this Apex code so far: 0
DEBUG|3. Number of DML statements used so far: 0
DEBUG|4. Amount of CPU time (in ms) used so far: 9
DEBUG|Continue processing. Not going to hit DML governor limits
DEBUG|Going to update 3 opportunities and governor limits will allow 10000
DEBUG|Number of DML statements used so far: 0
DEBUG|Final number of DML statements used so far: 1
DEBUG|Final heap size: 1819

Best Practice #8: 适时使用@future 功能

代码示例:

trigger accountAsyncTrigger on Account (after insert, after update) {
    //By passing the @future method a set of Ids, it only needs to be
    //invoked once to handle all of the data. 
    asyncApex.processAccount(Trigger.newMap.keySet());
}
global class asyncApex {
 
  @future 
  public static void processAccount(Set<Id> accountIds) {
       List<Contact> contacts = [select id, salutation, firstname, lastname, email from Contact where accountId IN :accountIds];
       for(Contact c: contacts){
 	 System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '], LastName[' + c.lastname +']');
 	                        c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
        }
        update contacts;
  }
}

知识点:@future 是异步调用的标记,带这个标记的方法被调用的时候不是马上执行,而是salesforce通过判断服务器端情况适时调用,这么做虽然不可预期执行时间,但是可以提交系统使用效率,避免触及salesforce的Limit。
注意点:如果异步方法和同步方法有可能同时更新同一条数据或者造成死锁的可能的话,需要引用锁的机制来解决。另外需要注意要批量处理数据。
异步方法调用也有Limit:
No more than 10 method calls per Apex invocation
No more than 200 method calls per Salesforce license per 24 hours
The parameters specified must be primitive dataypes, arrays of primitive datatypes, or collections of primitive datatypes.
Methods with the future annotation cannot take sObjects or objects as arguments.
Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.
It’s important to make sure that the asynchronous method

Best Practice #9: 如果有大量数据的处理逻辑,需要在测试Class也进行大数据量的测试

代码示例:

public class sampleTestMethodCls {

	static testMethod void testAccountTrigger(){
		
		//First, prepare 200 contacts for the test data
		Account acct = new Account(name='test account');
		insert acct;
		
		Contact[] contactsToCreate = new Contact[]{};
		for(Integer x=0; x<200;x++){
		    Contact ct = new Contact(AccountId=acct.Id,lastname='test');
		    contactsToCreate.add(ct);
		}
		
		//Now insert data causing an contact trigger to fire. 
		Test.startTest();
		insert contactsToCreate;
		Test.stopTest();	
	}	
}

知识点:
1:在测试Class的创建测试数据阶段,适时的创建大于200件数据来测试多批次处理逻辑是否有问题
2:测试一个事物里的执行可以使用Test.startTest();和Test.stopTest();来包围测试对象方法,从而准确的看出结果。

Best Practices #10:停止在代码里使用Hard Code

Bad Sample

for(Account a: Trigger.new){
     	 
   //Error - hardcoded the record type id
   if(a.RecordTypeId=='012500000009WAr'){     	  	
      //do some logic here.....
   }else if(a.RecordTypeId=='0123000000095Km'){
      //do some logic here for a different record type...
   }
    	 
}

Good Sample

//Query for the Account record types
     List<RecordType> rtypes = [Select Name, Id From RecordType 
                  where sObjectType='Account' and isActive=true];
     
     //Create a map between the Record Type Name and Id for easy retrieval
     Map<String,String> accountRecordTypes = new Map<String,String>{};
     for(RecordType rt: rtypes)
        accountRecordTypes.put(rt.Name,rt.Id);
     
      for(Account a: Trigger.new){
     	 
     	  //Use the Map collection to dynamically retrieve the Record Type Id
     	  //Avoid hardcoding Ids in the Apex code
     	  if(a.RecordTypeId==accountRecordTypes.get('Healthcare')){     	  	
     	  	 //do some logic here.....
     	  }else if(a.RecordTypeId==accountRecordTypes.get('High Tech')){
     	  	 //do some logic here for a different record type...
     	  }
     	 
     } 

知识点:Recordtype,Profile,user,queue,Group等都有单独的系统表存储数据,可以通过Select语句查询到,所以代码里需要这些数据的时候可以到系统表里查询,
原则上salesforce是不建议固定ID的,因为开发环境和生产环境的ID是不一样的,这样的Hardcode在开发环境上好用,在生产环境上是会出问题的。

Salesforce开发教程(二)上 1 开发预览   当你刚开始接触Salesforce开发,可能会有一些困惑,之前传统开发过程中遇到的问题(服务器配置、Jar包版本控制、程序驱动的安装等)仿佛都不见了,取而代之的是新鲜的困惑,暂时先不考虑这些;让我们先梳理一下,在Salesforce平台上开发时,当把代码提交给Salesforce的时候,服务器端到底发生了什么事情?   针对开发人员而言,请仔细观察上图Developer User终端,所有由开发人员编写的代码都将以元数据的形式存储在数据库中,然后等待用户触发执行。这个过程中有两点需要注意 阅读详情

相关推荐

salesforce sandbox的用户如何重置密码

在 Salesforce Sandbox 环境中,测试邮件地址通常会在邮箱后缀中添加 .invalid。通过上述方法,你可以成功重置密码并解决 Sandbox 环境中的邮箱限制问题。如果无法修改用户邮箱,管理员可以通过 Apex 直接设置新密码。,这会导致密码重置邮件无法送达。如果不想修改邮箱,可以通过设置邮件转发解决。

Debug yourself! 1111

Salesforce Apex开发笔记

Apex开发笔记

trjays的博客 3852

一文详解Apex的安装和使用教程(一款基于 PyTorch 的混合精度训练加速神器)

Apex的安装和使用教程(一款基于 PyTorch 的混合精度训练加速神器)

Tiger数学之家的博客 8万+

APEX开发过程中需要注意的小细节8

if (!} else {i++) {">// alert('页面上获取id:' + datas[i].id)//存入评分// console.log('map: ' +'id '+ key, '评分'+value)// }), value: score, //初始值//存入评分,动态获取})// // alert('页面上获取id:' + ids);//存入id。

clover_oreo的博客 987

18、深入了解Apex高级特性与Visualforce开发

本文深入探讨了Apex的高级特性,包括聚合查询、邮件收发和动态数据库操作,并全面介绍了Visualforce在Force.com平台上的开发方法。从Visualforce的MVC架构、控制器类型到视图组件的应用,文章提供了丰富的示例和最佳实践建议。此外,还涵盖了在生产环境中使用Visualforce时需要考虑的安全性、Governor限制和错误处理策略,帮助开发者构建高效、灵活的企业级应用。

metaverse5vr的博客 82

14、优化Apex与Visualforce代码编写的实用指南

本文详细介绍了优化Salesforce平台中Apex与Visualforce代码编写的实用技巧,涵盖测试上下文识别、REST Web服务开发、API版本控制、资源限制管理、调试日志跟踪、Visualforce架构理解、原生外观复用、标准与自定义控制器使用、代码重用策略、视图状态限制、字段集灵活布局、AJAX性能提升、全局变量使用、JavaScript远程调用注意事项以及页面安全性实践。通过这些技巧,开发者可以提升代码质量、安全性和可维护性,适用于各类Salesforce项目开发与部署场景。

css33的专栏 65

Oracle-APEX开发指南(2)

每个主题由定义应用程序外观的组件模板组成。在项目上开发的使用的是APEX4.1.1版本,在网页布局这块比较郁闷,创建Region的Column属性是在某个 Body内是全局的,在APEX4.2.5版本中,就变得相当的Easy,可以对子子…通常在APEX中对于记录的增删改是通过链接到新的页面去实现单条数据的更改。配置图表的Source的SQL,第一列为URL,即点击柱状条的一个链接,第二列为2)里的Show Labels的Label值.后面的SQL例为2)里的Show Values的Value。

2301_76957510的博客 2157

11、Force.com开发必备工具与资源指南

本文全面介绍了Force.com开发所需的各类工具和资源,涵盖开发工具(如Force.com IDE、开发者控制台、MavensMate插件)、模式浏览器、数据加载器以及实用工具和应用程序(如Force.com迁移工具、Salesforce Workbench、代码扫描工具)。同时,还推荐了开发者资源平台、开源项目和社区交流渠道,帮助开发者快速查找资料和解决问题。最后,总结了Apex开发的注意事项,帮助开发者写出更高效、安全的代码。

css33的专栏 61

APEX开发实践(七):一些小技巧集锦

很多时候,第一次打开页面的时候会做全表查询,然后再输入查询条件进行模糊查询。APEX里对中文的排序不友好,不是按照我们习惯的拼音来排序的。其实不是APEX的问题,是Oracle数据库的问题。用这种方法,可以在page的属性的CSS inline定义多个width的属性,然后使用到不同的列上。不过别忘了下载并修改app-icon.css里面的图标文件,并上传覆盖原来的。第一步,先在当前页面的属性里编辑加个CSS的定义。第二步,在你要改列宽的字段的属性里做个描述。第二步:就是把照片的引用放到所需的页面里。

m0_58767981的博客 346

28、Force.com 开发:批处理与集成实战

本文详细介绍了在Force.com平台上进行批处理和系统集成的实战经验。内容涵盖使用Batch Apex处理大量数据以避免 governor 限制、实现缺失时间表报告的示例应用、批处理的测试与注意事项,以及通过Apex调用RESTful和SOAP服务与外部系统交互的方法。此外,还讲解了如何利用Force.com的REST API从外部系统访问平台数据,并提供了一个企业绩效指标计算与传输的集成示例,帮助开发者理解不同集成方式的适用场景、优势与限制。

metaverse5vr的博客 66

apex开发及APEX程序剖析

APEX基础概念详解 APEX程序剖析详细说明 虽然不是新版,但入门很有参考价值

Salesforce(0):使用Apex Scheduler进行计划作业

????摘要 今天博主将给大家分享–Salesforce(0):使用Apex Scheduler进行计划作业。欢迎关注收藏! ????首先 Apex计划程序说明和最佳实践 Salesforce计划在指定时间执行该类。根据服务可用性,实际执行可能会延迟。 如果您计划从触发器安排课程,请格外小心。您必须能够保证触发器不会添加超出限制的计划班级。尤其要考虑API批量更新,导入向导,通过用户界面进行的批量记...

Mr_chen的博客 1052

salesforce Apex Code Developer's Guide

Chapter 1: Introducing Apex...............................................................................................................11 What is Apex?.........................................................................................................................................................................12 How Does Apex Work?..............................................................................................................................................13 What is the Apex Development Process?....................................................................................................................14 Using a Developer or Sandbox Organization...................................................................................................14 Learning Apex.................................................................................................................................................17 Writing Apex...................................................................................................................................................18 Writing Tests...................................................................................................................................................19 Deploying Apex to a Sandbox Organization...................................................................................................19 Deploying Apex to a Salesforce Production Organization...............................................................................20 Adding Apex Code to a Force.com AppExchange App..................................................................................20 When Should I Use Apex?..........................................................................................................................................20 What are the Limitations of Apex?......................................................................................................................

android开发 更新系统签名文件和Apex签名文件

android开发 更新系统签名文件和Apex签名文件

Android应用开发工程师 824

算力网:正在编织的“第二电网“

中国算力网:编织智能时代的"第二电网" 中国正在构建全国一体化算力网,目标让算力资源像水电一样即取即用。这一国家战略通过"东数西算"布局,将东部算力需求与西部清洁能源优势结合,形成三级时延圈(1ms城市级、5ms区域级、20ms国家级)。算力网采用三层架构:基础设施层的八大枢纽节点作为"发电厂",编排管理层的智能调度系统作为"调度中心",运营服务层提供标准化算力服务。关键技术包括算力路由、异构算力统一度量、无损网络和液冷技术等。

这只是一个博客 667

超声波探伤技术在风电叶片检测中的实战应用(含设备选型指南)

本文深入探讨了超声波探伤技术在风电叶片高空检测中的实战应用,重点分析了相控阵超声、激光超声等技术的选择与挑战。文章提供了详细的设备选型指南,对比了奥林巴斯、GE及国产品牌的优劣,并解读了典型缺陷的超声图谱特征,旨在帮助风电运维工程师安全、高效地完成叶片内部损伤的无损检测与预防性维护。

desk3的博客 885

ICM42670-P使用笔记

摘要:ICM-42670-P是一款集成三轴加速度计和陀螺仪的传感器,支持低噪声/低功耗模式。其特点包括:1)2.25KB可配置FIFO(与APEX功能共享存储);2)可编程中断系统,支持多种触发条件;3)APEX运动功能(计步、倾斜检测等);4)通过间接方式访问MREG1-3寄存器,需遵循特定时序要求;5)模式切换时需注意电源管理时序(如陀螺仪重启需20ms延时)。该芯片提供灵活的配置选项,适用于各类运动传感应用场景。(150字)

weixin_51699637的博客 3015

基于STM32的红外测温系统设计

为了实现本次的毕业设计,我搜集了大量的文献与资料,通过这些资料了解到红外测温的优点,与实现所需的基本器件,并设计了几个方案,最终选择了STM32作为主控芯片,为此还查阅了关于STM32的资料,在此次设计中采用的是MLX90614医用红外测温模块,通过查阅其数据手册了解其测量精度高且自带温度补偿,所以选择了该传感器作为红外测温模块,本次设计到此已经基本完成,硬件部分和软件部分的设计已基本完成。

weixin_112233的博客 1421

Apex--安装

参考:https://blog.youkuaiyun.com/weixin_42324771/article/details/105035362?ops_request_misc=&request_id=&biz_id=102&utm_term=windows%E5%AE%89%E8%A3%85apex&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-105035362 ...

weixin_44529105的博客 944

MS51内部振荡器

MS51内部有两个RC振荡器,一个高速16MHz或24MHz(HIRC),可通过HIRC24(RCTRIM1.4)位进 行选择配置,以及一个低速10 kHz(LIRC)。它们都可被选择用作系统时钟。通过设置HIRCEN (CKEN.5)位使能HIRC,设备上电时LIRC被使能。用户可设置OSC[1:0] (CKSWT [2:1])为[0,0]选择HIRC 作为系统时钟,设置OSC[1:0](CKSWT [1:0])为[1,0]选择LIRC作为系统时钟。注意:MS51上电后HIRC 和 LIRC都被...

seraphseraphhill2008的博客 808

【G4基础03】2.3 How to Specify Materials in the Detector

定义探测器材料

adelall的博客 489

纺织生产管理软件:Oracle二次开发_(1).纺织生产管理软件概述

纺织生产管理软件是指利用现代信息技术,对纺织企业的生产过程进行综合管理和控制的软件系统。它涵盖了从原料采购、生产计划、生产执行、质量检验到成品出库的整个生产流程。通过这种软件,企业可以实时监控生产状态,及时调整生产计划,确保生产的顺利进行。二次开发是指在现有的纺织生产管理软件基础上,根据企业的具体需求进行功能扩展和定制开发。通过二次开发,企业可以更好地满足自身生产管理的需求,提高软件的适用性和灵活性。-- 生成生产进度报表) ISBEGIN。

2401_87715305的博客 1033

51单片机也能玩转信号发生器?手把手教你用DAC0832和LM358输出四种标准波形

本文详细介绍了如何使用51单片机和DAC0832芯片搭配LM358运放,自制低成本信号发生器,实现正弦波、矩形波、三角波和锯齿波四种标准波形的输出。从硬件选型、电路设计到编程实现,手把手教你完成这一实用电子项目,总成本不到50元,适合电子爱好者和学生实践。

weixin_30530939的博客 551

Apex开发人员指南

Apex开发人员指南 调用顶点 匿名块 : 匿名块是Apex代码 , 他不会存储在元数据中 , 但是可以编译 触发器 : 可以使用触发器来调用Apex . Apex触发器使您呢不挂钩在更改Salesforce记录(例如插入 , 更新或者删除)之前或之后执行自定义操作 异步Apex: Apex提供了多种异步运行Apex代码的方法 , 选择最合适您需求的异步Apex功能 将Apex方法公开为SOAP...

皮卡丘 1386

【open judge】【程设】魔兽世界三开战!

#程设 魔兽世界三---开战!--------原以为会很容易ac,没想到写了好久,看来自己的水平还是亟待提高啊!有几个比较有趣的点:1. typeid(#include&lt;typeinfo&gt;)还是比较好用的,特别是本题当战士为wolf,iceman, dragon, ninja时有特殊技能,那么用typeid判断一下就很方便了。2. 对于这种输出很复杂的问题,往往通过使用文件的输入输出再...

weixin_40841416的博客 6073

【四足机器人项目实战】cheetah 3/mini运动控制工程解读(附C++代码)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、主程序入口1.代码流程2.终端设置信息提示二、用MiniCheetahHardwareBridge类构造一个hw的对象并初初始化1.2.3.4.三、运行硬件桥驱动【MiniCheetahHardwareBridge】1.2.3.4.四、1.2.3.4.总结参考资料 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对cheetah3/m

qq_35635374的博客 2615
上一篇: salesforce lighting 事件定义,绑定,触发之初探
下一篇: VisualForce Page经验分享
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值