首页 文章 精选 留言 我的

精选列表

搜索[增删改查],共8405篇文章
优秀的个人博客,低调大师

android 35 ListView增删改

MainActivity package com.sxt.day05_11; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.sxt.day05_11.entity.GeneralBean; public class MainActivity extends Activity { ListView mlvGeneral; List<GeneralBean> mGenerals; GeneralAdapter mAdapter; private static final int ACTION_DETAILS=0; private static final int ACTION_ADD=1; private static final int ACTION_DELETE=2; private static final int ACTION_UPDATE=3; int mPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); setListener(); } private void setListener() { mlvGeneral.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) { AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); builder.setTitle("选择以下操作") .setItems(new String[]{"查看详情","添加数据","删除数据","修改数据"}, new OnClickListener() {//倒的包是import android.content.DialogInterface.OnClickListener; @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case ACTION_DETAILS: showDetails(position);//这个position在mGenerals.get(position);调用,说明position是资源总条数范围, break; case ACTION_ADD: break; case ACTION_DELETE: mAdapter.remove(position);//调用适配器的删除方法 break; case ACTION_UPDATE: //启动修改的Activity,并将当前的军事家对象传递过去 Intent intent=new Intent(MainActivity.this, UpdateActivity.class); intent.putExtra("general", mGenerals.get(position));//mGenerals.get(position)的对象要实现序列化接口 mPosition=position; startActivityForResult(intent, ACTION_UPDATE);//要求返回结果,ACTION_UPDATE是requestCode break; } } private void showDetails(int position) { GeneralBean general=mGenerals.get(position); AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); builder.setTitle(general.getName()) .setMessage(general.getDetails()) .setPositiveButton("返回", null);//直接关闭,没有响应事件 AlertDialog dialog = builder.create(); dialog.show(); } }); AlertDialog dialog = builder.create(); dialog.show(); return true; } }); } private void initView() { mlvGeneral=(ListView) findViewById(R.id.lvGeneral); mAdapter=new GeneralAdapter(mGenerals, this); mlvGeneral.setAdapter(mAdapter); } private void initData() { String[] names=getResources().getStringArray(R.array.general); String[] details=getResources().getStringArray(R.array.details); int[] resid={ R.drawable.baiqi,R.drawable.caocao,R.drawable.chengjisihan, R.drawable.hanxin,R.drawable.lishimin,R.drawable.nuerhachi, R.drawable.sunbin,R.drawable.sunwu,R.drawable.yuefei, R.drawable.zhuyuanzhang }; mGenerals=new ArrayList<GeneralBean>(); for (int i = 0; i < resid.length; i++) { GeneralBean general=new GeneralBean(resid[i], names[i], details[i]); mGenerals.add(general); } } class GeneralAdapter extends BaseAdapter{ List<GeneralBean> generals; MainActivity context; public void remove(int position){//适配器移出方法,就是移除资源总数据, generals.remove(position); notifyDataSetChanged();//BaseAdapter的方法,执行后安卓系统会调用getView()方法重新绘制, } public void add(GeneralBean general){ mGenerals.add(general); notifyDataSetChanged(); } public void update(int position,GeneralBean general){ mGenerals.set(position, general); notifyDataSetChanged(); } public GeneralAdapter(List<GeneralBean> generals, MainActivity context) { super(); this.generals = generals; this.context = context; } @Override public int getCount() { return generals.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder=null; if(convertView==null){ convertView=View.inflate(context, R.layout.item_general, null); holder=new ViewHolder(); holder.ivThumb=(ImageView) convertView.findViewById(R.id.ivThumb); holder.tvName=(TextView) convertView.findViewById(R.id.tvName); convertView.setTag(holder); }else{//滚屏的时候重复利用convertView holder=(ViewHolder) convertView.getTag(); } GeneralBean general=generals.get(position); holder.ivThumb.setImageResource(general.getResid()); holder.tvName.setText(general.getName()); return convertView; } class ViewHolder{ ImageView ivThumb; TextView tvName; } } @Override //处理UpdateActivity返回的结果 protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode!=RESULT_OK){//判断resultCode return ; } switch (requestCode) {//判断requestCode case ACTION_UPDATE: GeneralBean general=(GeneralBean) data.getSerializableExtra("general");//获取修改完以后的对象 mAdapter.update(mPosition, general);//调用适配器的更新方法,mPosition是修改的对象在集合的索引 break; case ACTION_ADD: break; } } } mainactivity页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/lvGeneral" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 修改Activity: package com.sxt.day05_11; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.ImageView; import com.sxt.day05_11.entity.GeneralBean; public class UpdateActivity extends Activity { //要修改对象的名字(控件显示),详细信息(控件显示), EditText metName,metDetails; ImageView mivThumb;//图片 int mPhotoId;//图片id @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_update); initView(); initData(); setListener(); } private void setListener() { setOKClickListtener(); setCancelClickListener(); } private void setCancelClickListener() { findViewById(R.id.btnCancel).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); } private void setOKClickListtener() { findViewById(R.id.btnOK).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String details=metDetails.getText().toString(); String name=metName.getText().toString(); //不能根据图片控件获取图片的id,所以多用一个变量保存图片的id GeneralBean general=new GeneralBean(mPhotoId, name, details); Intent intent=new Intent(UpdateActivity.this, MainActivity.class); intent.putExtra("general", general); setResult(RESULT_OK, intent);//RESULT_OK是resultCode结果码 finish();//关闭当前页面 } }); } //接收数据 private void initData() { Intent intent = getIntent(); GeneralBean general=(GeneralBean) intent.getSerializableExtra("general"); //数据显示在控件里面 metDetails.setText(general.getDetails()); metName.setText(general.getName()); mivThumb.setImageResource(general.getResid());//图片是根据id获取的 mPhotoId=general.getResid();//保存图片id } private void initView() { //用布局实例化对象 metDetails=(EditText) findViewById(R.id.etDetails); metName=(EditText) findViewById(R.id.etName); mivThumb=(ImageView) findViewById(R.id.iv_updae_thumb); } } 修改Activity页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_updae_thumb" android:layout_width="80dp" android:layout_height="80dp" android:scaleType="fitXY" android:src="@drawable/baiqi"/> <EditText 可编辑的输入框 android:id="@+id/etName" android:layout_below="@id/iv_updae_thumb" android:layout_width="80dp" android:layout_height="wrap_content" android:text="白起"/> <EditText android:id="@+id/etDetails" android:layout_width="match_parent" android:layout_height="110dp" android:text="@string/detail" android:layout_toRightOf="@id/iv_updae_thumb"/> <Button android:id="@+id/btnOK" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="修改" android:layout_below="@id/etDetails" android:layout_marginLeft="50dp" android:layout_marginTop="20dp"/> <Button android:id="@+id/btnCancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="放弃" android:layout_below="@id/etDetails" android:layout_marginTop="20dp" android:layout_toRightOf="@id/btnOK" android:layout_marginLeft="50dp"/> </RelativeLayout> item_general.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > 横向 <ImageView android:id="@+id/ivThumb" android:layout_width="60dp" android:layout_height="60dp" android:scaleType="fitXY" 自动缩放 android:src="@drawable/baiqi"/> <TextView android:id="@+id/tvName" android:layout_width="wrap_content" android:layout_height="60dp" android:gravity="center_vertical" 内部垂直居中 android:textSize="20sp" android:text="白起" android:layout_marginLeft="10dp"/> </LinearLayout> 本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4889382.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

hive 增删改 实例

pom <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>0.11.0</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.2.0</version> </dependency> public class TeminalHiveCoreTest { public static void main(String[] args) throws SQLException { String tableName = " terminal "; String params ="appId,deviceMac,deviceId,deviceToken,deviceImsi,deviceModel,deviceManufacture,channel,appKey,userId,appVersion,versionCod,sdkType,sdkVersion,os,country,language,timezone,resolution,access,accessSubtype,carrier,cpu"; String partitionId ="appId"; String clusterId ="deviceToken"; String baseHdfsPath="hdfs://dev10.aoiplus.openpf:9000"; String hdfsPath=baseHdfsPath +"/user/hadoop/storm/terminalInfo_terminalInfo-3-0-1483076684221.log"; Connection connection = HiveJdbcConnection.getInstance().getConnection(HiveJdbcConnection.url, HiveJdbcConnection.user, HiveJdbcConnection.password); Statement stmt = connection.createStatement(); ResultSet res = null; HiveSqlDateDefineLanguage hqddl = new HiveSqlDateDefineLanguage().setCon(connection).setStmt(stmt); hqddl.dropTableByName(tableName); hqddl.createTableByParams(tableName, params,partitionId,clusterId); hqddl.loadSQL(tableName, hdfsPath); HiveSqlDateManageLanguage hqdml = new TermialHiveSqlDMLOperator().setCon(connection).setStmt(stmt).setRes(res); List<TerminalInfo> list = hqdml.findAll(tableName); System.out.println(list); HiveJdbcConnection.getInstance().close(res, stmt, connection); } } package com.curiousby.baoyou.cn.hive.base; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * @Type HiveJdbcConnection.java * @Desc * @author hadoop * @date 2016年12月29日 下午3:04:42 * @version */ public class HiveJdbcConnection { public static String driverName = "org.apache.hive.jdbc.HiveDriver"; public static String url ="jdbc:hive2://172.23.27.120:10000/default"; public static String user ="hive"; public static String password="hive"; static{ try { Class.forName(driverName); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new ExceptionInInitializerError(); } } private static HiveJdbcConnection instance = null; public static HiveJdbcConnection getInstance(){ if (instance == null ) { synchronized (HiveJdbcConnection.class) { if (instance == null ) { instance = new HiveJdbcConnection(); } } } return instance; } public Connection getConnection(String url,String user,String password) throws SQLException { return DriverManager.getConnection(url, user, password); } public void close(ResultSet rs, Statement st, Connection conn) { try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (st != null) st.close(); } catch (SQLException e) { e.printStackTrace(); } finally { if (conn != null) try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws SQLException { System.out.println(HiveJdbcConnection.getInstance().getConnection(url, user, password)); } } public class HiveSqlDateDefineLanguage implements SqlDateDefineLanguageInterface,SqlLoadData{ private Statement stmt; private ResultSet res; private Connection con; @Override public boolean createDatabase(String sql) { return false; } @Override public boolean createTable(String sql) { try { stmt.execute(sql); } catch (SQLException e) { e.printStackTrace(); return false; } return true; } /* CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path]*/ public boolean createTableByParams(String tableName,String params,String partitionedId,String clusteredId ){ String properties =""; String[] objects = params.split(","); for (int i = 0; i < objects.length; i++) { properties += objects[i] +" string,"; } properties = properties.substring(0, properties.length()-1); String sql =" create table " + tableName + " ("+ properties +") " +" comment '"+tableName+"' " // +" PARTITIONED BY ("+partitionedId+" string) " +" clustered by ("+clusteredId+") into 2 buckets " + " row format delimited fields terminated by ',' " // +" stored as orc " +" TBLPROPERTIES ('transactional'='true') " ; System.out.println(sql); return execute(sql); } @Override public boolean dropTable(String sql) { try { stmt.execute(sql); } catch (SQLException e) { e.printStackTrace(); return false; } return true; } public boolean dropTableByName(String tableName) { String sql ="drop table if exists " + tableName; return execute(sql); } public boolean execute(String sql) { try { stmt.execute(sql); } catch (SQLException e) { e.printStackTrace(); return false; } return true; } public Statement getStmt() { return stmt; } public ResultSet getRes() { return res; } public Connection getCon() { return con; } public HiveSqlDateDefineLanguage setStmt(Statement stmt) { this.stmt = stmt; return this; } public HiveSqlDateDefineLanguage setRes(ResultSet res) { this.res = res; return this; } public HiveSqlDateDefineLanguage setCon(Connection con) { this.con = con; return this; } @Override public boolean loadSQL(String tableName, String hdfsPath) { String sql = "LOAD DATA INPATH '"+hdfsPath+"' OVERWRITE INTO TABLE "+tableName; return execute(sql); } @Override public boolean loadLocalSQL(String tableName, String localPath) { String sql = "LOAD DATA local INPATH '"+localPath+"' OVERWRITE INTO TABLE "+tableName; return execute(sql); } } public abstract class HiveSqlDateManageLanguage extends SqlEntiyFormat<TerminalInfo> implements SqlDateManageLanguageInterface<TerminalInfo> { private Statement stmt; private ResultSet res; private Connection con; @Override public List<TerminalInfo> findAll(String tableName) { try { res = stmt.executeQuery("select * from " +tableName); List< TerminalInfo> list = formate(res); return list; } catch (SQLException e) { } return null; } @Override public TerminalInfo findOne(String key, String value) { return null; } @Override public TerminalInfo findOne(String sql) { return null; } @Override public List<TerminalInfo> findAllBySql(String sql) { return null; } @Override public boolean update(String sql) { return false; } @Override public boolean delete(String sql) { return false; } @Override public boolean insert(String sql) { return false; } @Override public boolean insert(TerminalInfo t) { return false; } public Statement getStmt() { return stmt; } public ResultSet getRes() { return res; } public Connection getCon() { return con; } public HiveSqlDateManageLanguage setStmt(Statement stmt) { this.stmt = stmt; return this; } public HiveSqlDateManageLanguage setRes(ResultSet res) { this.res = res; return this; } public HiveSqlDateManageLanguage setCon(Connection con) { this.con = con; return this; } } public class TermialHiveSqlDMLOperator extends HiveSqlDateManageLanguage{ @Override public void sqlMapper(ResultSet res, List<TerminalInfo> list) throws SQLException { TerminalInfo entity = new TerminalInfo(); entity .setAppId(res.getString(1)) .setDeviceMac(res.getString(2)) .setDeviceId(res.getString(3)) .setDeviceToken(res.getString(4)) .setDeviceImsi(res.getString(5)) .setDeviceModel(res.getString(6)) .setDeviceManufacture(res.getString(7)) .setChannel(res.getString(8)) .setAppKey(res.getString(9)) .setUserId(res.getString(10)) .setAppVersion(res.getString(1)) .setVersionCode(res.getString(12)) .setSdkType(res.getString(13)) .setSdkVersion(res.getString(14)) .setOs(res.getString(15)) .setCountry(res.getString(16)) .setLanguage(res.getString(17)) .setTimezone(res.getString(18)) .setResolution(res.getString(19)) .setAccess(res.getString(20)) .setAccessSubtype(res.getString(21)) .setCarrier(res.getString(22)) .setCpu(res.getString(23)) ; list.add(entity); } } public interface SqlLoadData { public boolean loadSQL(String tableName,String hdfsPath); public boolean loadLocalSQL(String tableName,String localPath); } public interface SqlMapper<T> { public void sqlMapper(ResultSet res , List< T> list) throws SQLException; } public abstract class SqlEntiyFormat<T> implements SqlMapper<T>{ public List<T> formate( ResultSet res) throws SQLException{ List< T> list = new ArrayList<T>(); while (res.next()) { sqlMapper(res, list); } return list; } } public interface SqlDateManageLanguageInterface<T> { public List<T> findAll(String tableName); public T findOne(String key ,String value); public T findOne (String sql); public List<T> findAllBySql (String sql); public boolean update (String sql); public boolean delete (String sql); public boolean insert(String sql); public boolean insert(T t); } /** * @Type SqlDateDefineLanguageInterface.java * @Desc CREATE DATABASE - 创建新数据库 ALTER DATABASE - 修改数据库 CREATE TABLE - 创建新表 ALTER TABLE - 变更(改变)数据库表 DROP TABLE - 删除表 CREATE INDEX - 创建索引(搜索键) DROP INDEX - 删除索引 * @author hadoop * @date 2016年12月29日 下午2:54:34 * @version */ public interface SqlDateDefineLanguageInterface { public boolean createDatabase(String sql); public boolean createTable(String sql); public boolean dropTable(String sql); public boolean dropTableByName(String tableName); } 捐助开发者 在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(右上角的爱心标志,支持支付宝和PayPal捐助),没钱捧个人场,谢谢各位。 谢谢您的赞助,我会做的更好!

优秀的个人博客,低调大师

【熵教育】Jacob-你所遗漏的SpringBoot日志管理知识——熵学院

Spring Boot对所有内部日志记录使用了Commons Logging,但是底层日志实现是开放的。可以为 Java Util日志、Log4J2和Logback。对于每种日志都预先配置为使用控制台输出和可选的文件输出。默认为Logback 日志配置 通过将相应的库添加到classpath可以激活各种日志系统,然后在classpath根目录下提供合适的配置文件可以进一步定制日志系统,配置文件也可以通过Spring Environment的logging.config属性指定。 以下文件会根据你选择的日志系统进行加载: 日志系统 定制配置 Logback logback-spring.xml,logback-spring.groovy,logback.xml或logback.groovy Log4j log4j.properties或log4j.xml Log4j2 log4j2-spring.xml或log4j2.xml JDK (Java Util Logging) logging.properties 注 如果可能的话,建议你使用-spring变种形式定义日志配置(例如,使用logback-spring.xml而不是logback.xml)。如果你使用标准的配置路径,Spring可能不能够完全控制日志初始化。 注 Java Util Logging从可执行jar运行时会导致一些已知的类加载问题,我们建议尽可能不使用它。 以下是从Spring Envrionment转换为System properties的一些有助于定制的配置属性: Spring Environment System Property Comments logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD 记录异常使用的关键字 logging.file LOG_FILE 如果指定就会在默认的日志配置中使用 logging.path LOG_PATH 如果指定就会在默认的日志配置中使用 logging.pattern.console CONSOLE_LOG_PATTERN 日志输出到控制台(stdout)时使用的模式(只支持默认的logback设置) logging.pattern.file FILE_LOG_PATTERN 日志输出到文件时使用的模式(如果LOG_FILE启用,只支持默认的logback设置) logging.pattern.level LOG_LEVEL_PATTERN 用来渲染日志级别的格式(默认%5p,只支持默认的logback设置) PID PID 当前的处理进程(process)ID(能够找到,且还没有用作OS环境变量) 所有支持的日志系统在解析配置文件时都能获取系统属性的值,具体可以参考spring-boot.jar中的默认配置。 log4j2配置 一份史诗级配置 /home/logs/log/dev \ \ \ \ </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> <AppenderRef ref="debug"/> <AppenderRef ref="info"/> <AppenderRef ref="warn"/> <AppenderRef ref="error"/> </Root> </Loggers> 各个文件输出到不同级别的目录 设置最大保存时间为15天 每个文件最大50M tomcat的日志 在properties文件添加如下配置: server.tomcat.basedir=/home/logs/log-api/tomcat-logs server.tomcat.accesslog.enabled=true server.tomcat.accesslog.pattern=%t %a "%r" %s %D (%D ms) server.use-forward-headers=true lombok的神组合 使用lombok的@Slf4j 注解,省去配置声明log的繁琐,提高开发效率。 idea的 grep console组合 Grep Console 自定义设置控制台输出颜色,这样控制台就能比较明显的看到警告或者错误的信息,方便查找问题 视频:https://space.bilibili.com/313762729/#/

优秀的个人博客,低调大师

Android之Sqlite的增删操作

今天写了个sqlite CRUD的操作实例,这里做个笔记。android的存储方式有很多有sharedpreferenced、file、xml、sqlite等。 sqlite的介绍网络上实在是多,俺还是直接代码。对用户的注册情况进行CRUD操作。 1、首先创建个DBHelper继承SQLiteOpenHelper packagecom.xzw.db.utils; importandroid.content.Context; importandroid.database.sqlite.SQLiteDatabase; importandroid.database.sqlite.SQLiteDatabase.CursorFactory; importandroid.database.sqlite.SQLiteOpenHelper; /** *该类是一个数据库的帮助类,用于创建数据库 *@authorxzw * */ publicclassDBHelperextendsSQLiteOpenHelper{ privatestaticfinalStringTAG="DBHelper"; privateStringdbName; privateStringtableName; privateStringcreateTableSql; /** * *@paramcontext上下文 *@paramdbName数据库名 *@paramversion数据库版本号 *@paramtableName表名称 *@paramcreateTableSql建表Sql */ publicDBHelper(Contextcontext,StringdbName,intversion,StringtableName,StringcreateTableSql){ super(context,dbName,null,version); this.dbName=dbName; this.tableName=tableName; this.createTableSql=createTableSql; } @Override publicvoidonCreate(SQLiteDatabasedb){ db.execSQL(createTableSql); } @Override publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){ Stringsql="DROPTABLEIFEXISTS"+tableName; db.execSQL(sql); onCreate(db); } } 2、创建User对象 packagecom.xzw.db.bean; publicclassUser{ privateIntegeruserid; privateStringuserName; privateStringpassword; privateStringsex; privatelongregTime; publicUser(){ } publicUser(StringuserName,Stringpassword,Stringsex,longregTime){ this.userName=userName; this.password=password; this.sex=sex; this.regTime=regTime; } publicUser(Integeruserid,StringuserName,Stringpassword,Stringsex, longregTime){ this.userid=userid; this.userName=userName; this.password=password; this.sex=sex; this.regTime=regTime; } publicIntegergetUserid(){ returnuserid; } publicvoidsetUserid(Integeruserid){ this.userid=userid; } publicStringgetUserName(){ returnuserName; } publicvoidsetUserName(StringuserName){ this.userName=userName; } publicStringgetPassword(){ returnpassword; } publicvoidsetPassword(Stringpassword){ this.password=password; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } publiclonggetRegTime(){ returnregTime; } publicvoidsetRegTime(longregTime){ this.regTime=regTime; } @Override publicStringtoString(){ //TODOAuto-generatedmethodstub return"[User]userid="+userid+",userName="+userName +",password="+password+",sex="+sex+",regTime=" +regTime; } } 3、创建UserStorage进行crud处理。 packagecom.xzw.db.utils; importjava.util.ArrayList; importjava.util.List; importcom.xzw.db.bean.User; importandroid.content.ContentValues; importandroid.content.Context; importandroid.database.Cursor; importandroid.database.sqlite.SQLiteDatabase; importandroid.util.Log; publicclassUserStorage{ privatestaticfinalStringTAG="UserStorage"; privatestaticfinalStringDB_NAME="user_data.db"; publicstaticfinalStringTABLE_NAME="user_data"; privatestaticfinalintDB_VERSION=1; staticfinalStringCOLUM_ID="_id"; staticfinalStringCOLUM_USER_NAME="username"; staticfinalStringCOLUM_PASSWORD="password"; staticfinalStringCOLUM_SEX="sex"; staticfinalStringCOLUM_REG_TIME="reg_time"; privateStringmCreateTableSql="createtableifnotexists"+TABLE_NAME +"("+COLUM_ID+"integerprimarykeyautoincrement," +COLUM_USER_NAME+"textnotnull," +COLUM_PASSWORD+"textnotnull," +COLUM_SEX+"text," +COLUM_REG_TIME+"bigintnotnull" +")"; privateDBHelperdbHelper; publicUserStorage(Contextcontext){ dbHelper=newDBHelper(context,DB_NAME,DB_VERSION,TABLE_NAME,mCreateTableSql); } /** *插入数据 *@paramcv *@return */ publiclonginsert(ContentValuescv){ //以写的方式创建或打开数据库 SQLiteDatabasedb=dbHelper.getWritableDatabase(); longresult=db.insert(TABLE_NAME,null,cv); db.close();//操作完成记得关闭数据库 if(result>0){ Log.i(TAG,"[Insert]success:"+result); }else{ Log.e(TAG,"Failedtoinsertinto"+TABLE_NAME); } returnresult; } /** *批量插入多条数据 *@paramcvs *@return */ publicintinsert(List<ContentValues>cvs){ intcount=0; SQLiteDatabasedb=dbHelper.getWritableDatabase(); for(ContentValuescv:cvs){ longid=insert(cv,db); count+=id>0?1:0; } db.close(); returncount; } /** *插入数据 *@paramcv *@paramdb *@return */ privatelonginsert(ContentValuescv,SQLiteDatabasedb){ longresult=db.insert(TABLE_NAME,null,cv); if(result>0){ Log.i(TAG,"[Insert]success:"+result); }else{ Log.e(TAG,"Failedtoinsertinto"+TABLE_NAME); } returnresult; } /** *根据id更新记录 *@paramcv *@paramid *@return */ publicintupdateUserById(ContentValuescv,Stringid){ SQLiteDatabasedb=dbHelper.getWritableDatabase(); intresult=db.update(TABLE_NAME,cv,"_id=?",newString[]{id}); db.close(); if(result>0){ Log.i(TAG,"[Update]success:"+result); }else{ Log.e(TAG,"Failedtoupate"+TABLE_NAME); } returnresult; } /** *获取所有列 *@return */ publicString[]getColumns(){ returnnewString[]{COLUM_ID,COLUM_USER_NAME,COLUM_PASSWORD,COLUM_SEX,COLUM_REG_TIME}; } publicList<User>getAllUser(){ List<User>users=newArrayList<User>(); SQLiteDatabasedb=dbHelper.getReadableDatabase(); Cursorcursor=db.query(TABLE_NAME,getColumns(),null,null,null,null,COLUM_ID); while(cursor.moveToNext()){ Useruser=fillUser(cursor); //添加user到集合中 users.add(user); } cursor.close();//游标使用完成后记得关闭 db.close(); returnusers; } privateUserfillUser(Cursorcursor){ Useruser=newUser(); user.setUserid(cursor.getInt(cursor.getColumnIndex(COLUM_ID))); user.setUserName(getValueByColumnName(cursor,COLUM_USER_NAME)); user.setPassword(getValueByColumnName(cursor,COLUM_PASSWORD)); user.setSex(getValueByColumnName(cursor,COLUM_SEX)); user.setRegTime(cursor.getLong(cursor.getColumnIndex(COLUM_REG_TIME))); returnuser; } /** *根据ID获取数据 *@paramid *@return */ publicUsergetUserById(Stringid){ SQLiteDatabasedb=dbHelper.getReadableDatabase(); Stringwhere="_id=?"; String[]selectionArgs=newString[]{id}; Cursorcursor=db.query(TABLE_NAME,getColumns(),where,selectionArgs,null,null,null); Useruser=null; if(cursor.moveToFirst()){ user=fillUser(cursor); } cursor.close();//游标使用完成后记得关闭 db.close(); returnuser; } /** *根据id删除记录 *@paramid *@return */ publicintdeleteById(Stringid){ SQLiteDatabasedb=dbHelper.getWritableDatabase(); intresult=db.delete(TABLE_NAME,"_id=?",newString[]{id}); db.close(); if(result>0){ Log.i(TAG,"[Delete]success:"+result); }else{ Log.e(TAG,"Failedtodeletefrom"+TABLE_NAME); } returnresult; } //获取字段值 privateStringgetValueByColumnName(Cursorcursor,StringcolumnName){ returncursor.getString(cursor.getColumnIndex(columnName)); } /** *清空表数据 *@paramid *@return */ publicvoidclear(){ SQLiteDatabasedb=dbHelper.getWritableDatabase(); db.delete(TABLE_NAME,null,null); db.close(); } } 4、编写UserService进行业务处理。 packagecom.xzw.db.utils; importjava.util.ArrayList; importjava.util.List; importandroid.content.ContentValues; importandroid.content.Context; importandroid.os.storage.StorageManager; importcom.xzw.db.bean.User; publicclassUserService{ privateUserStorageuserStorage; publicUserService(Contextcontext){ userStorage=newUserStorage(context); } /** *保存用户 * *@paramuser *@return */ publiclongsaveUser(Useruser){ ContentValuescv=fillContentValues(user); longcount=userStorage.insert(cv); returncount; } /** *批量保存用户 *@paramusers *@return */ publiclongsaveUser(List<User>users){ List<ContentValues>contentValues=newArrayList<ContentValues>(); for(Useruser:users){ ContentValuescv=fillContentValues(user); contentValues.add(cv); } longcount=userStorage.insert(contentValues); returncount; } /** *根据id修改数据 *@paramuser *@return */ publicintupdateUserById(Useruser){ ContentValuescontentValues=fillContentValues(user); returnuserStorage.updateUserById(contentValues,user.getUserid().toString()); } /** *获取所有用户信息 *@return */ publicList<User>getAllUser(){ returnuserStorage.getAllUser(); } /** *根据id获取用户信息 *@paramid *@return */ publicUsergetUserById(Stringid){ returnuserStorage.getUserById(id); } /** *根据id删除数据 *@paramid *@return */ publicintdeleteById(Stringid){ returnuserStorage.deleteById(id); } /** *删除所有数据 */ publicvoiddeleteAll(){ userStorage.clear(); } /** *填充数据 *@paramuser *@return */ privateContentValuesfillContentValues(Useruser){ //以下代码比较多地方会用带,故将其抽象成为方法。也是一种优化手段 ContentValuescv=newContentValues(); cv.put(UserStorage.COLUM_USER_NAME,user.getUserName()); cv.put(UserStorage.COLUM_PASSWORD,user.getPassword()); cv.put(UserStorage.COLUM_SEX,user.getSex()); cv.put(UserStorage.COLUM_REG_TIME,user.getRegTime()); returncv; } } 以上是整个业务流程了。现在使用AndroidTestCase进行测试 创建TestUser继承AndroidTestCase packagecom.xzw.db; importjava.util.ArrayList; importjava.util.List; importcom.xzw.db.bean.User; importcom.xzw.db.utils.UserService; importcom.xzw.db.utils.UserStorage; importandroid.test.AndroidTestCase; importandroid.util.Log; publicclassTestUserextendsAndroidTestCase{ privatestaticfinalStringTAG="TestUser"; /** *测试添加用户 */ publicvoidtestSave(){ UserServiceuserService=newUserService(this.getContext()); Useruser=newUser("xzw","123456","男",System.currentTimeMillis()); userService.saveUser(user); } /** *测试批量添加用户 */ publicvoidtestBatchSave(){ UserServiceuserService=newUserService(this.getContext()); List<User>users=newArrayList<User>(); for(inti=0;i<10;i++){ Useruser=newUser("hh-"+i,"123456",(i%2==0)?"男":"女",System.currentTimeMillis()); users.add(user); } userService.saveUser(users); } publicvoidtestGetAllUser(){ UserServiceuserService=newUserService(this.getContext()); List<User>users=userService.getAllUser(); for(Useruser:users){ Log.i(TAG,user.toString()); } } publicvoidtestGetUserById(){ UserServiceuserService=newUserService(this.getContext()); Useruser=userService.getUserById("2"); Log.i(TAG,user.toString()); } publicvoidtestUpdateUser(){ UserServiceuserService=newUserService(this.getContext()); Useruser=userService.getUserById("2"); user.setUserName("测试用户"); userService.updateUserById(user); } publicvoidtestDeleteById(){ UserServiceuserService=newUserService(this.getContext()); userService.deleteById("1"); } } 代码全部编写完毕,运行前需要在AndroidManifest.xml文件添加 <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.xzw.db" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <!--添加测试--> <uses-libraryandroid:name="android.test.runner"/> <activity android:name=".MainActivity" android:label="@string/title_activity_main"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <!--添加测试目标包--> <instrumentationandroid:name="android.test.InstrumentationTestRunner" android:targetPackage="com.xzw.db"android:label="TestsforMyApp"/> </manifest> 以上就是整个sqlite crud的操作了。 查询所有用户信息: 根据id进行查询。 update后查询的结果。 以上就是完整的过程了。 本文转自xuzw13 51CTO博客,原文链接:http://blog.51cto.com/xuzhiwei/1054965,如需转载请自行联系原作者

优秀的个人博客,低调大师

Go语言恶意软件暴20倍

根据以色列安全公司Intezer的最新报告《地鼠年:2020年恶意软件综述》,在过去的四年中,随着国家黑客和网络犯罪纷纷转向新的技术生态系统,用Go编程语言编写的新恶意软件激增了2000%。 报告显示,尽管Go语言(有时被称为Golang),大约在九年前就被首次用于恶意软件,但直到2019年它才在网络犯罪分子中流行。 从那时起,Go已成为一种越来越普遍的选择,主要是因为它可以在Windows、Linux和Mac操作系统上运行,并且对研究人员进行逆向工程提出了难度较大的挑战。 Intezer还称赞Go具有“非常易于使用的编写良好的网络堆栈”。 报告指出,去年俄罗斯支持的黑客使用Zebrocy恶意软件的变体攻击了东欧国家。俄罗斯黑客还使用Go语言开发了WellMess恶意软件,该恶意软件针对英国、加拿大和美国的新冠疫苗研究人员。 在网络犯罪方面,Go语言编写的恶意软件包括用于发动DDoS攻击和非法开采加密货币的僵尸网络(IPStorm),以及全部用Go语言编写的勒索软件变体(Nefilim、EKANS)。 Intezer总结说,用户将需要专门的运行保护工具来应对Go恶意软件不断增长的威胁。 “我们看到攻击者针对操作系统的恶意软件来自同一Go代码库。由于许多因素,传统的防病毒程序很难识别Go恶意软件。基于代码重用的检测方法已证明是有效的,特别是在检测恶意软件家族方面。随着更多有价值的资产转移到云中,Go恶意软件对云环境的攻击也可能会增加。” 【本文是51CTO专栏作者“安全牛”的原创文章,转载请通过安全牛(微信公众号id:gooann-sectv)获取授权】 戳这里,看该作者更多好文

优秀的个人博客,低调大师

问题这样,拒做背锅侠

技术的锅太多,到底该不该你背? 话说这天一大早,那个悲催的中年架构师大刘又被手机微信群给炸醒。部门的运维兄弟在公司微信群里说: 短信的生产环境服务器 CPU 占用率过高,疯狂报警。是不是你们昨天上线看门狗导致的? 大刘迷了巴登的想了想,没错,昨天确实给短信服务装上了看门狗。但是看门狗服务肯定不会有问题(架构师必备的蜜汁自信),而且上线之前各轮测试也都测过了,没见过这个想象啊。 难道是测试妹子没测试到位?难道线上短信应用自身出现了问题? 生产无小事,小事更不能忽视,主要是怕扣绩效奖金。大刘迅速打开电脑,打开 VPN ,远程登上短信生产服务器,开始大刘最拿手的 2W1H 三板斧诊断之旅。 接下来的诊断内容有点烧脑,节奏有点快,请大家坐稳扶好。 1. 病号是谁(WHO)? 大刘拿出控制台诊断仪器,输入 top 命令一探究竟。我勒个去,不看不知道一看吓一跳,PID 为 1878 的病号,CPU 占用居然 200% 多。 问题算是定位到了,但是 PID 为 1878 的病号到底是谁,难道真是昨天上线的看门狗 ? 虽然大刘久经职场,但是排查生产问题时,内心还是比较忐忑,毕竟这是生产环境。 说时迟那时快,只见大刘一个命令输入: ps -ef | grep 1878 定睛一看,原来是放屁瞅别人,短信服务自己在作祟,和看门狗没关系,大刘心里一下子平缓了不少。 锅找到了主儿,其实这个时候大刘完全可以把这个问题甩给短信开发团队,但是大刘最喜欢做的不是甩锅,而是打破砂锅刨到底。 2. 病号哪里出了问题(WHERE)? 为什么 1878 号病人占用 CPU 会这么高呢? 只见黑乎乎的控制台诊断仪器上,大刘熟练的输入: jstack -l 1878 >> 1878号病历.log 这样便得到一份 1878 号病人的病历详情单,一会儿用得上。 到底 1878 号病人的哪个部位出了问题呢? 话没说完,只见大刘又在控制台诊断仪器上,输入一个: top -Hp 1878 白板黑字,把 1878 号病人的器官信息全部列了出来。 看到结果,甚是一惊,PID 代号为 8721 的器官占用 CPU 100% 多。 疑惑油然而生,这个 PID 代号 为 8721 的器官是啥,是头、是眼睛、还是胳膊腿呢?这些器官展示的 PID 列都是昵称,都这么善于伪装,如何揭露它的真面目呢? 还好大刘有高招,借助照妖镜算法,熟练的输入: printf "%x\n" 8721 果真使得代号为 8721 的器官,现了真身,真实身份居然是 2211 的呼吸道,怪不得病号一直气喘吁吁,上气不接下气。 到这一步还无法对症下药啊,还需要进一步确诊 2211 的呼吸道到底出了什么幺蛾子,导致 1878 号病人一直气喘吁吁,上气不接下气? 只见黑乎乎的控制台诊断仪器上,大刘再次飞一般的在输入: grep 2211 -A20 1878号病历.log 诊断结果随之显示在诊断仪器上。 曾经背了很多锅的大刘,看到诊断结果心里乐了一下,一眼就看出是高并发情况下用了 HashMap 的问题(请大家们自行寻找谷歌、百度,就不在此深入展开啦),终于拨开云雾见青天。 3. 如何对症下药( HOW )? 在大刘行云流水没有一丝一毫的拖泥带水般的神操作下,1878 号病人的诊断也就结束了,这个锅就彻底被打破了。 术业有专攻,大刘就可以郑重的告诉短信开发同事具体原因了,捉得病根,开发同事也就可以对症下药啦。 大刘这套行走江湖的诊断问题方式你 get 到了没?大刘自己简单概括为 2W1H 三板斧:病号是谁、病号哪里出了问题、对症下药。 1、病号是谁?(WHO) 第一步:采用 top 命令,找出 CPU 占用最高的病号 PID ; 第二步:通过 ps -ef | grep PID 查看病号对应的真实身份。 2、病号哪里出了问题?(WHERE) 第一步:采用 jstack -l PID >> PID.log 获取病号的各器官信息的病历单; 第二步:采用 top -Hp PID 拿到占用 CPU 最高的器官昵称 PID ; 第三步:采用 printf "%x\n" PID 根据器官昵称 PID 的拿到器官真实身份 TID ; 第四步:采用 grep TID -A20 pid.log 根据 TID 去病历单中匹配,确定是哪出了问题。 3、捉得病根、便可拿出医药箱,对症下药啦。(HOW) 作为程序猿,工作中难免会遇到不少类似这样的问题。面对问题,你如果像无头苍蝇一样乱撞,撞得头破血流依然不知道缘由,在背锅即将成为现实时,那就不妨试试大刘的 2W1H 三板斧的诊断方式,说不定会帮你快速定位、解决线上问题,毕竟快速的解决生产问题会把损失降到最低。 最后,想对大家说一句: 作为程序猿,一定要有程序猿的态度。避免背锅,拒绝甩锅,打破砂锅,从你我做起。 你好,我是四猿外,一家上市公司的技术总监,管理的技术团队一百余人。 我从一名非计算机专业的毕业生,转行到程序员,一路打拼,一路成长。 我会把自己的成长故事写成文章,把枯燥的技术文章写成故事。 欢迎关注我的公众号:四猿外

优秀的个人博客,低调大师

asp.net core 2.0 缺补漏

asp.net core 2.0 一些有用有趣的设置. 面向(targeting)不同的.net版本: 打开asp.net core 2.0的项目文件: xxx.csproj, 这部分: <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramework> </PropertyGroup> TargetFramework就是指向的版本. 也可以指向多个.net版本, 那就使用TargetFrameworks, 例如: <TargetFrameworks>netcoreapp2.0;net47</TargetFrameworks> 编译后, 在bin/debug文件夹下就会有两个文件夹: Microsoft.AspNetCore.All 并不是标准的Nuget包, 它不包含任何代码或dll, 它作为一个metapackage, 引用了很多其他的包而已 Program.cs asp.net core 应用其实就是一个控制台应用, 运行了asp.net core相关的库而已. program.cs里面都是对于宿主和环境的配置. 在这里, 已经进行了默认的配置. 但是如果你想捕获asp.net core启动时候的错误, 并显示错误页面, 那么: .CaptureStartupErrors(true) 是否应该监听Microsoft.AspNetCore.Hosting.Server.IServer制定的url(ipv4, v6, hostname, localhost, unix socket), 可以使用: .PreferHostingUrls(true) 监听指定的url: .UseUrls("http://0.0.0.0:5000") 使用ApplicationInsights: .UseApplicationInsights() Startup.cs startup里面是用来预加载/配置服务和中间件的. ConfigureServices方法用来注册服务. Configure方法用来配置请求管道. 添加mvc中间件, 就在ConfigureServices方法里: services.AddMvc(); 使用mvc中间件, 在Configure里: app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); Dependency Injection 每次调用创建一个实例: services.AddTransient<IEmailService, EmailService>(); 每次http请求创建一个实例: services.AddScoped<IEmailService, EmailService>(); 只创建一个实例: services.AddSingleton<IEmailService, EmailService>(); 如果你不想让容器自动dispose掉服务(容器会自动调用服务的Dispose方法), 那么你应该手动添加服务, 例如: services.AddSingleton(new EmailService()); http 请求管道中间件的顺序 最佳实践: 1. 异常处理中间件 2. 静态文件中间件 3. 用户验证中间件 4. mvc中间件 创建自定义中间件 有两种方法: 1. 直接在Startup里面写 可以使用四个方法: Run, Map, MapWhen, Use. Run方法直接短路, 返回Response. Map用于处理分支, 判断请求地址的开头, 为分支添加特定中间件等等 MapWhen也是处理分支, 但是可以控制分支的状态 Use, 可以调用下一个中间件(next.Invoke())或者短路请求. 2. 单独写一个类 public class CommunicationMiddleware { private readonly RequestDelegate _next; public CommunicationMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { await _next.Invoke(context); } } 然后再写一个extension 方法: public static class CommunicationMiddlewareExtension { public static IApplicationBuilder UseCommunicationMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CommunicationMiddleware>(); } } 最后在Startup的Configure里调用即可: app.UseCommunicationMiddleware(); app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); Url Redirection 和 Url Rewriting 他们是不同的. url redirection是从服务器端绕了一圈, 然后回到客户端, 客户端收到301或者302之后, 再调用新地址. url rewriting是服务器端自己完成的, 客户端一无所知. 可以这样来使用Url Rewriting: var options = new RewriteOptions() .AddRewrite("NewUser", "/User/Registration/Index", false); app.UseRewriter(options); 异常处理 默认情况下400到599的错误信息都不会显示. 就会显示一个异常页面. 但是可以自定义错误页面: app.UseStatusCodePages("text/plain", "HTTP ERROR: Status Code: {0}"); 多个环境 asp.net core 2.0默认先加载appSettings.json, 然后根据环境不同再加载appSettings.{environment}.json. 如果有必要就覆盖或替换一些值. 根据环境使用不同的Startup文件: .UseStartup("AssemblyName") StartupDevelopment, StartupStaging, StartupProduction. Web Api的三种风格 RTC, 包含Action的Name Rest, 它是一种http协议的最佳实践方式而已. 主要目的是管理和控制资源. HATEOAS, 客户端通过遍历http response里面的超媒体链接, 可以动态导航到所需的资源, 酷. 使用HATEOAS, 需要安装包Halcyon.mvc下面是我的关于ASP.NET Core Web API相关技术的公众号--草根专栏:

优秀的个人博客,低调大师

C++缺补漏3,赶紧的

如何判断一段程序是由C 编译程序还是由C++编译程序编译的? 答案: #ifdef __cplusplus cout<<"c++"; #else cout<<"c"; #endif 如何打印出当前源文件的文件名以及源文件的当前行号? 答案: cout << __FILE__ ; cout<<__LINE__ ; __FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。 main 主函数执行完毕后,是否可能会再执行一段代码,给出说明? 答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行。 #include <iostream> using namespace std; int fn1() { printf( "next.\n" ); return 0; } int fn2() { printf( "executed " ); return 0; } int fn3() { printf( "is " ); return 0; } int fn4() { printf( "This " ); return 0; } int _tmain(int argc, _TCHAR* argv[]) { _onexit( fn1 ); _onexit( fn2 ); _onexit( fn3 ); _onexit( fn4 ); printf( "This is executed first.\n" ); return 0; } 输出结果为: The _onexit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order.The functions passed to _onexit cannot take parameters. 类成员函数的重载、覆盖和隐藏区别? 答案: a.成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。 (5)const的区别 b.覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有virtual 关键字。 c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/28/2422418.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

C++缺补漏4,赶紧的

请说出const与#define 相比,有何优点? 答案:1)const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。 2)有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。 当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk)答案:肯定不是零。举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。 描述内存分配方式以及它们的区别?1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。 main 函数执行以前,还会执行什么代码?答案:全局对象的构造函数会在main 函数之前执行。 C++是不是类型安全的?答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。 有哪几种情况只能用intialization list 而不能用assignment? 答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。 define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少? 答案:i 为30 New delete 与malloc free 的联系与区别?答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor. 1、写一个“标准”宏,这个宏输入两个参数并返回较小的一个。 .#define Min(X, Y) ((X)>(Y)?(Y):(X))//结尾没有; 2、嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。 while(1){}或者for(;;) 3、关键字static的作用是什么? 定义静态变量 4、关键字const有什么含意? 表示常量不可以修改的变量。 5、关键字volatile有什么含意?并举出三个不同的例子? 提示编译器对象的值可能在编译器未监测到的情况下改变。 int (*s[10])(int) 表示的是什么啊 int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。 1.有以下表达式: int a=248; b=4;int const c=21;const int *d=&a; int *const e=&b;int const *f const =&a; 请问下列表达式哪些会被编译器禁止?为什么? *c=32;d=&b;*d=43;e=34;e=&a;f=0x321f; *c 这是个什么东东,禁止 *d 说了是const, 禁止 e = &a 说了是const 禁止 const *f const =&a; 禁止 2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3; 有两种解法, 一种用算术算法, 一种用^(异或) a = a + b; b = a - b; a = a - b; or a = a^b;// 只能对int,char.. b = a^b; a = a^b; or a ^= b ^= a; 3.c和c++中的struct有什么不同? c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private 4.#i nclude <stdio.h> #i nclude <stdlib.h> void getmemory(char *p) { p=(char *) malloc(100); strcpy(p,"hello world"); } int main( ) { char *str=NULL; getmemory(str); printf("%s/n",str); free(str); return 0; } 程序崩溃,getmemory中的malloc 不能返回动态内存, free()对str操作很危险 5.char szstr[10]; strcpy(szstr,"0123456789"); 产生什么结果?为什么? 长度不一样,会造成非法的OS 6.列举几种进程的同步机制,并比较其优缺点。 原子操作 信号量机制 自旋锁 管程,会合,分布式系统 7.进程之间通信的途径 共享存储系统 消息传递系统 管道:以文件系统为基础 11.进程死锁的原因 资源竞争及进程推进顺序非法 12.死锁的4个必要条件 互斥、请求保持、不可剥夺、环路 13.死锁的处理 鸵鸟策略、预防策略、避免策略、检测与解除死锁 15. 操作系统中进程调度策略有哪几种? FCFS(先来先服务),优先级,时间片轮转,多级反馈 8.类的静态成员和非静态成员有何区别? 类的静态成员每个类只有一个,非静态成员每个对象一个 9.纯虚函数如何定义?使用时应注意什么? virtual void f()=0; 是接口,子类必须要实现 10.数组和链表的区别 数组:数据顺序存储,固定大小 连表:数据可以随机存储,大小可动态改变 12.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点? 应用层 表示层 会话层 运输层 网络层 物理链路层 物理层 tcp /udp属于运输层 TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。 与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。 tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好 udp: 不提供稳定的服务,包头小,开销小 1:(void *)ptr 和 (*(void**))ptr的结果是否相同?其中ptr为同一个指针 .(void *)ptr 和 (*(void**))ptr值是相同的 2:int main() { int x=3; printf("%d",x); return 1; } 问函数既然不会被其它函数调用,为什么要返回1? mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息 1,要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? *((void (*)( ))0x100000 ) ( ); 首先要将0x100000强制转换成函数指针,即: (void (*)())0x100000 然后再调用它: *((void (*)())0x100000)(); 用typedef可以看得更直观些: typedef void(*)() voidFuncPtr; *((voidFuncPtr)0x100000)(); 2,已知一个数组table,用一个宏定义,求出数据的元素个数 #define NTBL #define NTBL (sizeof(table)/sizeof(table[0])) 面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈? 进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。 每个线程有自己的堆栈。 DLL中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈? 以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃 unsigned short A = 10; printf("~A = %u\n", ~A); char c=128; printf("c=%d\n",c); 输出多少?并分析过程 第一题,~A =0xfffffff5,int值 为-11,但输出的是uint。所以输出4294967285 第二题,c=0x10,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是128,所以输出-128。 这两道题都是在考察二进制向int或uint转换时的最高位处理。 分析下面的程序: void GetMemory(char **p,int num) { *p=(char *)malloc(num); } int main() { char *str=NULL; GetMemory(&str,100); strcpy(str,"hello"); free(str); if(str!=NULL) { strcpy(str,"world"); } printf("\n str is %s",str); getchar(); } 问输出结果是什么?希望大家能说说原因,先谢谢了 输出str is world。 free 只是释放的str指向的内存空间,它本身的值还是存在的. 所以free之后,有一个好的习惯就是将str=NULL. 此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的, 尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出world来。 这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。 当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的,只不过。。。。。。。。楼上都说过了,最好别这么干。 char a[10],strlen(a)为什么等于15?运行的结果 #i nclude "stdio.h" #i nclude "string.h" void main() { char aa[10]; printf("%d",strlen(aa)); } sizeof()和初不初始化,没有关系; strlen()和初始化有关。 char (*str)[20];/*str是一个数组指针,即指向数组的指针.*/ char *str[20];/*str是一个指针数组,其元素为指针型数据.*/ long a=0x801010; a+5=? 0x801010用二进制表示为:“1000 0000 0001 0000 0001 0000”,十进制的值为8392720,再加上5就是8392725罗 1)给定结构struct A { char t:4; char k:4; unsigned short i:8; unsigned long m; };问sizeof(A) = ? 给定结构struct A { char t:4; 4位 char k:4; 4位 unsigned short i:8; 8位 unsigned long m; // 偏移2字节保证4字节对齐 }; // 共8字节 2)下面的函数实现在一个数上加一个数,有什么错误?请改正。 int add_n ( int n ) { static int i = 100; i += n; return i; } 当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在 static上? // 帮忙分析一下 #i nclude<iostream.h> #i nclude <string.h> #i nclude <malloc.h> #i nclude <stdio.h> #i nclude <stdlib.h> #i nclude <memory.h> typedef struct AA { int b1:5; int b2:2; }AA; void main() { AA aa; char cc[100]; strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz"); memcpy(&aa,cc,sizeof(AA)); cout << aa.b1 <<endl; cout << aa.b2 <<endl; } 答案是 -16和1 首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit. 经过strcpy和memcpy后,aa的4个字节所存放的值是: 0,1,2,3的ASC码,即00110000,00110001,00110010,00110011 所以,最后一步:显示的是这4个字节的前5位,和之后的2位 分别为:10000,和01 因为int是有正负之分 所以:答案是-16和1 求函数返回值,输入x=9999; int func ( x ) { int countx = 0; while ( x ) { countx ++; x = x&(x-1); } return countx; } 结果呢? 知道了这是统计9999的二进制数值中有多少个1的函数,且有 9999=9×1024+512+256+15 9×1024中含有1的个数为2; 512中含有1的个数为1; 256中含有1的个数为1; 15中含有1的个数为4; 故共有1的个数为8,结果为8。 1000 - 1 = 0111,正好是原数取反。这就是原理。 用这种方法来求1的个数是很效率很高的。 不必去一个一个地移位。循环次数最少。 int a,b,c 请写函数实现C=a+b ,不可以改变数据类型,如将c改为long int,关键是如何处理溢出问题 bool add (int a, int b,int *c) { *c=a+b; return (a>0 && b>0 &&(*c<a || *c<b) || (a<0 && b<0 &&(*c>a || *c>b))); } 分析: struct bit { int a:3; int b:2; int c:3; }; int main() { bit s; char *c=(char*)&s; cout<<sizeof(bit)<<endl; *c=0x99; cout << s.a <<endl <<s.b<<endl<<s.c<<endl; int a=-1; printf("%x",a); return 0; } 输出为什么是 4 1 -1 -4 ffffffff 因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100 当c为有符合数时, c = 100, 最高1为表示c为负数,负数在计算机用补码表示,所以c = -4;同理 b = -1; 当c为有符合数时, c = 100,即 c = 4,同理 b = 3 位域 : 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为: struct 位域结构名 { 位域列表 }; 其中位域列表的形式为: 类型说明符 位域名:位域长度 例如: struct bs { int a:8; int b:2; int c:6; }; 位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如: struct bs { int a:8; int b:2; int c:6; }data; 说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明: 1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如: struct bs { unsigned a:4 unsigned :0 /*空域*/ unsigned b:4 /*从下一单元开始存放*/ unsigned c:4 } 在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。 2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。 3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如: struct k { int a:1 int :2 /*该2位不能使用*/ int b:3 int c:2 }; 从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。 二、位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名•位域名 位域允许用各种格式输出。 main(){ struct bs { unsigned a:1; unsigned b:3; unsigned c:4; } bit,*pbit; bit.a=1; bit.b=7; bit.c=15; pri 改错: #i nclude <stdio.h> int main(void) { int **p; int arr[100]; p = &arr; return 0; } 解答: 搞错了,是指针类型不同, int **p; //二级指针 &arr; //得到的是指向第一维为100的数组的指针 #i nclude <stdio.h> int main(void) { int **p, *q; int arr[100]; q = arr; p = &q; return 0; } 下面这个程序执行后会有什么错误或者效果: #define MAX 255 int main() { unsigned char A[MAX],i;//i被定义为unsigned char for (i=0;i<=MAX;i++) A[i]=i; } 解答:死循环加数组越界访问(C/C++不进行数组越界检查) MAX=255 数组A的下标范围为:0..MAX-1,这是其一.. 其二.当i循环到255时,循环内执行: A[255]=255; 这句本身没有问题..但是返回for (i=0;i<=MAX;i++)语句时, 由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去. struct name1{ char str; short x; int num; } struct name2{ char str; int num; short x; } sizeof(struct name1)=8,sizeof(struct name2)=12 在第二个结构中,为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐),在x后还要补齐2个字节,这样就是12字节。 intel: A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)? static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。 他们都放在数据区,但是编译器对他们的命名是不同的。 如果要使变量在其他模块也有意义的话,需要使用extern关键字。 struct s1 { int i: 8; int j: 4; int a: 3; double b; }; struct s2 { int i: 8; int j: 4; double b; int a:3; }; printf("sizeof(s1)= %d\n", sizeof(s1)); printf("sizeof(s2)= %d\n", sizeof(s2)); result: 16, 24 第一个struct s1 { int i: 8; int j: 4; int a: 3; double b; }; 理论上是这样的,首先是i在相对0的位置,占8位一个字节,然后,j就在相对一个字节的位置,由于一个位置的字节数是4位的倍数,因此不用对齐,就放在那里了,然后是a,要在3位的倍数关系的位置上,因此要移一位,在15位的位置上放下,目前总共是18位,折算过来是2字节2位的样子,由于double是8字节的,因此要在相对0要是8个字节的位置上放下,因此从18位开始到8个字节之间的位置被忽略,直接放在8字节的位置了,因此,总共是16字节。 第二个最后会对照是不是结构体内最大数据的倍数,不是的话,会补成是最大数据的倍数 上面是基本问题,接下来是编程问题: 本人很弱,这几个题也搞不定,特来求救: 1)读文件file1.txt的内容(例如): 12 34 56 输出到file2.txt: 56 34 12 (逆序) 2)输出和为一个给定整数的所有组合 例如n=5 5=1+4;5=2+3(相加的数不能重复) 则输出 1,4;2,3。 望高手赐教!! 第一题,注意可增长数组的应用. #i nclude <stdio.h> #i nclude <stdlib.h> int main(void) { int MAX = 10; int *a = (int *)malloc(MAX * sizeof(int)); int *b; FILE *fp1; FILE *fp2; fp1 = fopen("a.txt","r"); if(fp1 == NULL) {printf("error1"); exit(-1); } fp2 = fopen("b.txt","w"); if(fp2 == NULL) {printf("error2"); exit(-1); } int i = 0; int j = 0; while(fscanf(fp1,"%d",&a[i]) != EOF) { i++; j++; if(i >= MAX) { MAX = 2 * MAX; b = (int*)realloc(a,MAX * sizeof(int)); if(b == NULL) { printf("error3"); exit(-1); } a = b; } } for(;--j >= 0;) fprintf(fp2,"%d\n",a[j]); fclose(fp1); fclose(fp2); return 0; } 第二题. #i nclude <stdio.h> int main(void) { unsigned long int i,j,k; printf("please input the number\n"); scanf("%d",&i); if( i % 2 == 0) j = i / 2; else j = i / 2 + 1; printf("The result is \n"); for(k = 0; k < j; k++) printf("%d = %d + %d\n",i,k,i - k); return 0; } #i nclude <stdio.h> void main() { unsigned long int a,i=1; scanf("%d",&a); if(a%2==0) { for(i=1;i<a/2;i++) printf("%d",a,a-i); } else for(i=1;i<=a/2;i++) printf(" %d, %d",i,a-i); } 兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程. void inverse(char *p) { if( *p = = '\0' ) return; inverse( p+1 ); printf( "%c", *p ); } int main(int argc, char *argv[]) { inverse("abc\0"); return 0; } 借签了楼上的“递规反向输出” #i nclude <stdio.h> void test(FILE *fread, FILE *fwrite) { char buf[1024] = {0}; if (!fgets(buf, sizeof(buf), fread)) &nb ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/28/2422454.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

C++缺补漏2,赶紧的

先来看一段代码把: #include <iostream> #include <typeinfo> using namespace std; void foo(void) { unsigned int a = 6; int b = -20; (a+b > 6) ? puts("> 6") : puts("<= 6"); } int _tmain(int argc, _TCHAR* argv[]) { foo(); unsigned int c=1; int d=-5; cout<<typeid(d+c).name()<<endl; cout<<d+c<<endl; return 0; } 输出的结果是: 有没有一点吃惊? 这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是 ">6"。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。 下面再来看看一段代码: #include <iostream> #include <malloc.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char *ptr=NULL; ptr=(char*)malloc(0); if(ptr==NULL){ cout<<"Got a null pointer"<<endl; cout<<*ptr<<endl; }else{ cout<<"Got a valid pointer"; } free(ptr); return 0; } 输出的结果为: 我询问一些技术大牛,她们的回答是: malloc(0)是未定义的,返回NULL或者不是NULL,都是满足ISO C标准的。有些操作系统会返回一个指针 Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子: #define dPS struct s * typedef struct s * tPS; 以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么? 这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子: dPS p1,p2; tPS p3,p4; 第一个扩展为 struct s * p1, p2; . 上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。晦涩的语法 16 . C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么? int a = 5, b = 7, c; c = a+++b; 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成: c = a++ + b; 因此, 这段代码持行后a = 6, b = 7, c = 12。 7.C++中为什么用模板类。 答:(1)可用来创建动态增长和减小的数据结构 (2)它是类型无关的,因此具有很高的可复用性。 (3)它在编译时而不是运行时检查数据类型,保证了类型安全 (4)它是平台无关的,可移植性 (5)可用于基本数据类型 ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/28/2422093.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Oracle

Oracle

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

JDK

JDK

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。